3

We have a large legacy application to which we recently added jersey/jax-rs based functionality. The idea is that we will implement new functionality for our UI layer as restful APIs. A first prototype is working nicely - but it is lacking proper error handling.

I had a closer look at the initial implementation, and what I found is that there is a "base task" class that registers a specific ExceptionMapper. The idea is that there will be different and disjunct sub tasks extending that base task.

My initial thought was: each sub task should have its own, specific exception mapper.

In other words: I see two different options:

  • one central exception mapper, that works all exceptions thrown within any of the numerous sub tasks we are going to implement over time
  • one mapper per sub task

Option 1 leading to well, one central piece of code - but much less flexible compared to option 2 (it starts with things like: normally our sub tasks have their own "log id" when writing logs - but a central mapper doesn't know about its context and has to use the very same log id all the time).

My question is: are the hard technical facts (or well established "best procedures") to select between the two options?

GhostCat
  • 127,190
  • 21
  • 146
  • 218
  • I think this would be similar setup as with Java exception handlers in general: specialized exception handlers for exception that need to receive special treatment (such as those you mention that need specific context info) or can be recovered from, and one catch-all somewhere else that would report unhandled/unexpected/etc. exceptions, similarly to how `Thread.uncaughtExceptionHandler` works. – M. Prokhorov Aug 08 '17 at 15:16

2 Answers2

2

In my opinion, one general exception handler to catch everything public class GenericExceptionMapperProvider implements ExceptionMapper<Throwable>, and, you can continue adding more exception handlers as needed.

JAX-RS supports exception inheritance as well. When an exception is thrown, JAX-RS will first try to find an ExceptionMapper for that exception’s type. If it cannot find one, it will look for a mapper that can handle the exception’s superclass. It will continue this process until there are no more superclasses to match against. read more

Here a post that I wrote: http://blog.nafiux.com/posts/jax-rs-exception-handling/

Ignacio Ocampo
  • 2,649
  • 1
  • 16
  • 28
  • Thanks for your input. I thought about this for some more time; and decided in the end to put up a self-answer. But again- thank you very much for your helpful input. – GhostCat Aug 14 '17 at 13:43
0

After doing some more research resp. design discussions, I realize that basically my question goes into the wrong direction:

  • first of all, there is no need for a catching-everything-mapper. Instead one can extend java.util.logging.Handler to then configure a resource to use a org.glassfish.jersey.logging.LoggingFeature.
  • coming from there: ideally, an exception mapper should just do that: map a specific exception to some expected "result".

In other words: our solution boils down to

  • using the "logging" capabilities of jersey to log any incoming exception
  • having some generic and some "per component" exception mappers
GhostCat
  • 127,190
  • 21
  • 146
  • 218