Oleg,

Thanks for digging into this.

Oleg Kalnichevski wrote:

One of the major shortcomings of the existing architecture is unclear
and convoluted exception handling framework.


Here's the list of my personal gripes with it

- there is no clear-cut distinction between protocol exceptions (that
are in most cases fatal) and transport exception (that are in most cases
recoverable). As a result possible recovery strategy is not clear (at
least to me)

- Why on earth does HttpException have to extend URIException? That's
just lunacy on a massive scale.

- HttpClient#excecuteMethod & HttpMethodBase#execute declare but never
throw IOException


I'd add my gripe that I simply don't know what exceptions to expect to get! It occurs to me that it might be a good idea to enumerate the possible failure points for which we want to establish a contract and stick to those expectations.

The scenarios I can think of, as suggested by some of our existing exception classes, and what I can recall of cases I've worried about.

   * Authentication failure - AuthenticationException
   * Authentication protocol failure - MalformedChallengeException
   * Bad URI - URIException
   * Cookie protocol failure - MalformedCookieException
   * Date protocol failure - DateException
   * Server not responding to initial attempt at communication -
     IOException?
   * Server not found (DNS lookup failure?) - IOException?
   * "protocol failure" - currently triggered by a failure to find
     HTTP/1.0 or HTTP/1.1 status response line - call this
     HttpProtocolFailure?
   * Just about any communications/IO failure during send - perhaps we
     call this HttpSendFailure - but wrap underlying IOException?
   * Just about any communications/IO failure during response - perhaps
     we call this HttpReceiveFailure - but wrap underlying IOException?
   * Too many redirects - perhaps HttpExcessiveRedirectException?

There are some exceptions that currently occur internally that shouldn't be exposed to clients, such as attempts to write to a recycled connection that can fail since the connection is stale. Those failures clearly should generate retries with a fresh connection as we do now, and are really an artifact of how Java sockets work, not something that clients of HttpClient care about.

With the scenarioes above, I only see two exceptions that might possible need to "wrap" other exceptions, so I lean towards the simpler approach that Oleg outlined.

-Eric.


I personally see two ways of fixing things


1) "Back to the roots" -------------------------
This approach is basically about going back to a very simple, but clear
framework that existed before but got messed up on the way toward
beta-1.


org.apache.commons.httpclient.HttpException (Root protocol exception)
 |
 +-- org.apache.commons.httpclient.cookie.MalformedCookieException
 |
 +-- org.apache.commons.httpclient.auth.AuthenticationException
 |
 +-- ...

java.io.IOException (Root transport exception; | all i/o exceptions considered recoverable. Period)
|
+-- java.io.InterruptedIOException (timeout)
|
+-- ...


Pros:
- simplicity
- no need to 'warp' or 'chain' exceptions. No need for Commons-lang
Cons:
- Some i/o exceptions MIGHT be unrecoverable, but at the moment I can't
think of a single one
- It may not be apparent to everyone that a request that has caused an
IOException can be retired


2) Go elaborate
-----------------
org.apache.commons.lang.exception.NestableException (or equivalent)
|
+-- org.apache.commons.httpclient.HttpException (Root exception)
|
+-- ...httpclient.HttpProtocolException (Root protocol exception)
| |
| +-- ...httpclient.cookie.MalformedCookieException
| |
| +-- ...httpclient.auth.AuthenticationException
| |
| +-- ...
|
+-- ...httpclient.HttpTransportException | (should 'wrap' java.io.IOException)
|
+-- ...httpclient.RecoverableHttpException
| |
| +-- ...httpclient.TimeoutHttpException
| |
| +-- ...httpclient.ConnectTimeoutHttpException
| |
| +-- ...httpclient.IOTimeoutHttpException
|
+-- ...httpclient.InterruptedHttpException


Pros:
- flexibility
- clarity
Cons:
- complexity
- most likely requires an external dependency


In my opinion we MUST get exception handling right before we do anything
else. Exception handling is a foundation of any flexible architecture.


I personally can live with either of these two approaches. If you see
other alternatives, please share your ideas

Cheers

Oleg


--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]








--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to