Logging and exception handling are like two peas in a pod. When a problem happens in your Java code, that typically means you have an exception that needs to be handled, and of course, any time an error or unanticipated event occurs, that occurrence should be logged appropriately.
When performing exception handling in Java, there are really two options the developer has at their disposal:
- Handle the exception when it is thrown and recover from the error as it happens
- Re-throw the exception so another part of the application can deal with the issue
In layered applications, option number two is particularly common, as there is typically a single layer at the top of the execution stack that is designed specifically for the task of handling and recovering from exceptions. So it is very common to see layered applications re-throwing and re-throwing exceptions until they bubble up to the top. It can be a very effective strategy.
However, one of the most common mistakes developers make is logging the exception before it is re-thrown. This practice must be regarded as an anti-pattern of the highest order.
Exceptions should be logged when they are handled, and only when they are handled. There is no doubt that logging an exception in every catch block is done with good intentions, but doing so makes tracking down exceptions and resolving issues a complete nightmare. The exception ends up getting logged multiple times in multiple layers, and when quality engineers start tracking through the log files, there experiencing is suffocating and troubleshooters have no idea where to start and when to finish.
The problem is significant, but it is easily resolved. The resolution? Just get used to logging exceptions when, and only when, they are handled. That puts all of the exception logging in one place, in one file on one layer of the applications. It makes enterprise applications easier to troubleshoot and in then end, makes them easier to maintain as well.