users@jersey.java.net

Re: [Jersey] Jersey client and exceptions

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Thu, 12 Feb 2009 11:51:19 +0100

On Feb 12, 2009, at 11:20 AM, Denis AH-KANG wrote:

>
>
> On Thu, Feb 12, 2009 at 10:17 AM, Paul Sandoz <Paul.Sandoz_at_sun.com>
> wrote:
>
> On Feb 12, 2009, at 12:46 AM, Denis AH-KANG wrote:
>
> Hi all,
>
> I have some questions about the jersey client and its exceptions.
> Why does the client only throw runtime exceptions
> (ClientHandlerException and
> UniformInterfaceException)?
>
>
>
> ClientHandlerException is thrown is there is an error reading/
> writing the response e.g. an IOException.
>
> UniformInterfaceException is thrown when status code of the HTTP
> response indicates a response that is not expected. And in your
> example below you need to refer to UniformInterfaceException.
>
>
> Actually, the problem is that these exceptions extend a runtime
> exception and Java typechecking doesn't force to catch that kind of
> exceptions. According to me, HTTP errors must be mapped to java
> exception that we have to deal with (e.g. force catching).
> That article http://scv.bu.edu/Doc/Java/tutorial/java/exceptions/runtime.html
> shows you what i think.
>

Thanks i know the controversy :-)

Note that the VM compatible language Scala has no checked exceptions,
and with good reason:

   http://www.scala-lang.org/node/256

   Compile-time checking of exceptions sounds good in theory, but in
practice has not worked well. Programmers tend to
   write catch clauses that catch too many exceptions, thus swallowing
exceptions and decreasing reliability.

Errors tend to be hidden and are thus very hard to track down.


>
>
>
>
> Actually, I need to use the client and manage the most common HTTP
> responses (400, 404, 500...).
> For the moment, I catch the client exception and get the status code
> from it. It means I need
> to create a switch case to handle each case. For instance:
>
> catch(ClientHandlerException e) {
> switch(e.getResponse().getResponseStatus()):
> case 400:
> //some code
> case 404:
> //some code
> ....
> }
>
> Do you know if there's a better way to use the jersey client?
>
>
> The approach taken by the client API is by default to handle common
> cases are not considered exceptional and uncommon cases like
> response errors as exception cases.
>
> So if i do a:
>
> String s = resource.get(String.class)
>
> then a UniformInterfaceException will be thrown if the response has
> a status code >= 300 and the response contains no entity.
>
> If you do this:
>
> ClientResponse r = resource.get(ClientResponse.class);
>
> then UniformInterfaceException will not be thrown. And it is up to
> you to handle the response status in normal code blocks, for example:
>
> ClientResponse r = resource.get(ClientResponse.class);
> switch(r.getResponseStatus()):
>
> case 400:
> //some code
> case 404:
> //some code
> ....
> }
>
> See the JavaDoc for more details:
>
> https://jersey.dev.java.net/source/browse/*checkout*/jersey/tags/jersey-1.0.1/api/jersey/com/sun/jersey/api/client/UniformInterface.html
>
> Don't you think it'll useful to extends the
> UniformInterfaceExceptions for the common HTTP error codes?
> For instance:
>
> try {
> ...
> } catch (NotFoundException nfe) {
> //HTTP 404
> } catch (InternalSystemException ise) {
> // HTTP 500
> } catch (UniformInterfaceException)
> // Don't need to use getResponseStatus: typechecking has already
> given the information
> }
>

This has it's appeal for common status codes.

Note that a UniformInterfaceException can be thrown for 204 (No
Content) when the client attempts to retrieve a response entity.


> If you agree, I can contribute on this part.

Sure! log an issue and attache a patch.

I recommend making such classes inner static classes of
UniformInterfaceException.

Paul.