简体   繁体   中英

Exception handling architecture for Java EE projects

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").

Exceptions are pure gold for you trying to find out what went wrong. Treat them accordingly!

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).

I strongly discourage the practice of swallowing exceptions. This is the best way to waste so much time investigating the origin of a problem. I had so many wtf moments when I eventually found the hidden exception in an empty catch clause. I agree with Thorbjørn regarding the fact that most of the time you have one top try catch. Inside it I find myself using many methods which may throws exception, and to avoid error handling code, I prefer to catch the exceptions just in the top catch.
About centralization , I believe that your log files should be central enough.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM