Best Practices In Production Level Exception Handling In Java Applications
What is happening in exceptional handling at production level due to the presently prevalent coding style?
Ideally, code sent to production servers as the final build of the version should be totally bug free. That is not possible in real-world applications. Also, exceptions do not necessarily occur only due to bugs. A temporary system failure, an uncaught nullpointer exception, and other such cases can also lead to exceptions.
In a typical DevOps setting, we have come to love our logs. Where exceptions should be well, exceptions that occur only in the most ‘lost cause’ scenarios that disrupt the normal functioning of the Java application. However, because of our love for the written record, we write logs for even the most trivial exceptions.
This leads to a lot of noise in the operational logs, which can often bury the really serious exceptions as a mere statistical figure. Unless the exception occurs a significant number of times in a short time window, say a 1000 users not able to checkout a cart exactly at 1 PM which shows a visible spike in the exception log, the maintenance folks cannot detect critical system failures.
Let us revisit the original purpose of writing exception handling code
Java provides a lot of default exception handling logs. Developers let the logs be, and write their own code in addition. It has become such a routine activity that we often forget the real purpose of writing exception handling code – which is to generate actionable insights from the logs.
How does irrational overuse of exceptions affect your exception handling mechanisms?
What we are doing instead, is generating chunks of files of meaningless log that does not provide any insight into what a ‘developer can do’ to fix the recurring exceptions.
Consider the two major exception log wasters :
• Business Errors : They occur when user does something that is not permitted by the business rules of the application. E.g Checking out an empty cart.
• System Errors : They occur when the application demands something that the OS cannot provide. E.g Asking for a restricted file.
How should exceptions be logged?
True exceptions are only those, which a developer cannot predict. The ones that require action for resolution. The ones that will kill your application or put it in a limbo, while they kill a thread and other threads are waiting for the murdered thread to complete its operations.
Curb exceptions in Source Code
The main purpose of exceptions in Java is debugging, not catching the errors due to application logic. The errors therein should be handled in the code itself. Unactionable exceptions just contribute to noise and affect the performance, stability, and monitoring while committing the most serious offense of hiding the real exceptions.
Checked exceptions are the main culprits of noise. Most developers overlook them in the code. And if they do, they throw unchecked exceptions while handling the checked exceptions!
Here are some pointers to handle exceptions effectively:
• Use exceptions only if they are exceptional.
• Use checked exceptions in recoverable scenarios and runtime exceptions for programming errors.
• Favor standard exceptions. If you have to throw an exception, consider the level of abstraction.
• Document all exceptions from each method.
• Do not ignore exceptions. Write action code where necessary.
How excessive logging is hampering effective issue resolution?
The top 10 exceptions that make 97.3% of the total exception logs are:
If you fix only these 10 errors in your application, you will manage to reduce almost all of your operational noise, which will help you focus on the more serious issues.
Blind logging of exceptions is also not commercially viable as the costs for disk storage, log management software, and the operational resources are significant.
To sum up
Exceptions are scenarios that cannot be foreseen. Predictable exceptions should be handled in application code, while action code should be written in the try-catch block for true exceptions. A good application code fixes the 10 most frequent exceptions, and has a very low level of operational noise.