users@jersey.java.net

Re: [Jersey] exception handling best practices

From: Marc Hadley <Marc.Hadley_at_Sun.COM>
Date: Mon, 22 Feb 2010 13:15:02 -0500

On Feb 22, 2010, at 1:04 PM, Chris Carrier wrote:

> But it's true that one would need a new ExceptionMapper for every new
> Exception type? I guess it's somewhat a question of taste but for me
> this:
>
> catch (RecordNotFoundException e){
> return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage).build;
> }
>
> Is much simpler and more self-documenting than:
>
> @Provider
> public class RecordNotFoundExceptionMapper implements
> ExceptionMapper<RecordNotFoundException> {
> public Response toResponse(RecordNotFoundException ex) {
> return Response.status(404).entity(ex.getMessage()).build();
> }
> }
>
I can see your point but I found all those repetitive catch clauses awkward. As an example at one point I needed to add error logging and it was much easier to add it in one place rather than many.

BTW, ExceptionMappers can be supplied for the base class if all your application exceptions have a common one.

Marc.


> It would be lovely if everyone who might be looking at my code will be
> familiar with the details of Jersey but I work in a company and that's
> just not the way things work. I would rather my code is
> self-documenting and clear for anyone who is familiar with Java than
> hope that the person knows about Jersey's Provider magic.
>
> That's most of what I like about Jersey. Anyone can look at a method
> annotated with @GET @Consumes etc and it's pretty clear what is
> happening there even if you've never heard of JAX-RS.
>
> Like I said though at some point it's a matter of taste. Both
> approaches have their downsides.
>
> Chris
>
> On Mon, Feb 22, 2010 at 9:50 AM, Moises Lejter <moilejter_at_gmail.com> wrote:
>> Hmm - I would have thought it would go the other way ...
>> Using the "string of catch clauses", there is boilerplate in every class
>> that can run into a specific domain exception, to list the code to run in
>> that case. Using the ExceptionMappers, the code for a specific domain
>> exception is listed exactly once, in the ExceptionMapper for that one
>> class...
>> It is true that using ExceptionMappers things are more decentralized, and
>> people have to know JAX-RS/Jersey ... But as to the second - if they don't,
>> maybe they shouldn't be maintaining those HTTP classes?
>> Moises
>> On Mon, Feb 22, 2010 at 11:44 AM, Chris Carrier <ctcarrier_at_gmail.com> wrote:
>>>
>>> That might be true I was just throwing out my approach. Personally
>>> I'm not a huge fan of the @Provider mechanism as it's not intuitive.
>>> You just have to know how Jersey/JAX-RS works and that there are these
>>> magic provider classes that may be configuring behavior. I'd rather
>>> keep things simple and use as much plain Java as possible. I don't
>>> think the string-of-catches will be a problem upkeep wise and anyone
>>> else can look at my code and pretty much understand what's going on.
>>> Using the exceptionMapper would you have an individual mapper for
>>> every exception type? Seems like a ton of boilerplate.
>>>
>>> Chris
>>>
>>> On Mon, Feb 22, 2010 at 9:32 AM, Moises Lejter <moilejter_at_gmail.com>
>>> wrote:
>>>> Hmm - if by "HTTP classes" you mean those annotated with JAX-RS/jersey
>>>> annotations, then I think Marc was talking about using ExceptionMapper
>>>> classes to capture the service-layer exceptions, then returning an HTTP
>>>> response with the proper status code and message, taken from those
>>>> exceptions. As a result, you would not need that "string of catch
>>>> clauses"
>>>> - your HTTP classes would simply ignore exceptions, and concentrate on
>>>> the
>>>> "correct" scenario, and the ExceptionMappers would be invoked by Jersey
>>>> on
>>>> its own, when the HTTP class throws an exception that it doesn't handle
>>>> (namely, your domain exceptions from the service layer), and compute and
>>>> return the right error status code and message for you...
>>>> No string of catch clauses => more maintainable code?
>>>> Moises
>>>>
>>>> On Mon, Feb 22, 2010 at 11:18 AM, Chris Carrier <ctcarrier_at_gmail.com>
>>>> wrote:
>>>>>
>>>>> The approach I landed on was to keep the HTTP error handling as
>>>>> contained in the Jersey annotated endpoint classes as possible. So
>>>>> basically from my HTTP classes I delegate to some kind of service
>>>>> class layer. So if I am trying to post an account or something I
>>>>> would create an Exception maybe something like
>>>>> 'AccountCreationException', 'AccountValidationException' etc that get
>>>>> thrown from the service layer. Then in my HTTP class I simply catch
>>>>> those and map them to whatever status code I want
>>>>> (AccountNotFoundException -> 404 etc...). And since the exceptions
>>>>> were raised in the service layer they already contain a human readable
>>>>> error message. It keeps it pretty manageable because there is just a
>>>>> string of catch clauses that handle your HTTP error mapping.
>>>>>
>>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>