I am trying to gather input on how other Java EE programmers do their exception handling. Do you centralize the error handling (eg. a Servlet filter)?
Do you create different exception types for the different application layers (persistence, service, etc)?
Do you just swallow the exceptions and not throw them up the chain at all?
What other paradigms are there in exception handling architecture? Which do you use and why?
The persistence layer, if it's implemented using JPA or Hibernate, already has its own exceptions, which are runtime exceptions.
The service layer throws runtime exceptions when illegal arguments are passed (when they're supposed to be validated by the presentation layer), or checked exceptions when a recoverable error occurs (example: the chosen name already exists in database).
Each controller of the presentation layer deals with the checked exceptions thrown by the business services that it calls, to provide a meaningful error message and let the user recover from the error (example: re-display the form and ask the user to choose another name)
All the other runtime exceptions, coming from the presentation layer, the business layer, or the persistence layer, are handled by one or several global exception handlers (most UI frameworks support them), which log the exception and throw a more or less generic error message (example: "Unexpected error occurred", "Some other user modified or removed the object you tried to modify").
Swallowing exceptions is only acceptable in the very few cases, where it is actually the appropriate action.
Checked exceptions in Java generally force you to consider how to handle errors close to the location where it actually happened. Note that it can be perfectly acceptable to wrap the exception in a DomainException (or an appropriate sub-class thereof) and send it up the calling chain to a location that can actually handle it and recover gracefully.
In most cases you have a top most try-catch which allow you to catch all exceptions and handle them. This is why it is so important to provide as much logic (by wrapping it in an exception which make sense to you), so this handler can act accordingly.
For known cases, the appropriate action can then be taken.
For unknown cases it is a matter of failing very loudly, as you have your system in an unexpected state. Log as much as you possibly can - because you may not be able to reproduce it otherwise - and enter a suitable state (exiting, deny further service, or just carry on as appropriate for your model).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With