I know exception handling is a topic often discussed in the world of Java. I’ve read a few threads on here and SO as well.
https://stackoverflow.com/questions/2169339/exception-handling-in-a-java-web-application
I find myself identifying with principles such as Do not suppress or ignore exceptions, Do not catch top-level exceptions, and avoid anti-patterns like Log and Throw.
http://today.java.net/article/2006/04/04/exception-handling-antipatterns#throwingException
http://www.onjava.com/pub/a/onjava/2003/11/19/exceptions.html?page=2
Question #1, is there a different standard of practice when it comes to web applications? For example, is it a legitimate use case to catch Exception
for logging purposes and then throw it up the stack?
function void xyz() throws Exception {
try {
} catch (Exception e) {
LOG.error("ERROR: " + e);
throw e;
}
}
function void otherFuncA() throws Exception {
xyz();
}
function void otherFuncB() {
try {
xyz();
} catch (Exception e) {
LOG.error("ERROR: " + e);
throw e;
}
}
I am finding it very hard to accept as a practice because it is generating so much unnecessary code (see otherFuncA
and otherFuncB
), affecting the function calls all through the different layers (DAO, Service, Controller, etc.)
Question #2, do I lose information about an error (let’s say what caused a NullPointerException
) if I let unexpected, unchecked exceptions float up to the Controller layer and then, and ONLY then, handle it there (catch Exception
and throw stack trace)? As opposed to logging immediately, and re-throwing (seen above).
Of course, I will still check for specific exception types where applicable.
I seem to find the stack trace is often a better indicator of what went wrong vs. which specific field was causing an error… I am really interested in input from more experienced developers and what best practices/reasoning guide your exception handling.
2
1) No.
2) Not if you put relevant information into the Exception’s message – I find that a much preferable alternative.
6
A very good use-case for the Log and Throw pattern is when your framework passes the exception to the front-end. This can happen for instance with web applications that handle errors locally, but also in client server systems where you throw an exception and have the exception be encapsulated and sent to the client (JAX-WS will do this, and send an error response containing the exception).
But normally you also want to have the exception in the log of the originating server. And this pattern provides this exact behaviour.
Note that – when possible – you want the Log and Throw pattern to be part of an interceptor like solution, so that you don’t have to sprinkle your code with this pattern. But sometimes that is just not convenient or possible.
What an exception is?
Definition: An exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the program’s instructions.
Source: The JavaTM tutorial.
… and there are two types of events the normal flow could be hindered by:
unrecoverable: those it can be done nothing about. An unresponsive service without a fallback is unrecoverable.
recoverable: those it can be done something about. Using a fallback for an unresponsive service call is a recoverable call.
About those unrecoverable the user is informed, while those recoverable don’t exist for the user. When an exception is raised try to recover from it until it becomes unrecoverable when it should bubble up until the component concerned with user readable messages, messages the way log messages or user readable error messages are.