Search This Blog

Guide to Java Exception Handling Best Practices

In this guide, I would like to explain Java Exception Handling Best Practices. We can follow these best practices in the day to day project work. This post belongs to Java Best Practices Series category.Trust me exception handling in Java isn’t an easy topic. Beginners find it hard to understand and even experienced developers can spend hours discussing how and which Java exceptions should be thrown or handled.Let's discuss each of the Exception Handling Best Practices with examples.

1. Clean up Resources in a Finally Block or Use a Try-With-Resource Statement

A common mistake occurs when closing the resources. The most common mistake is to close the resource at the end of the try block. For Example:

The problem is that this approach seems to work perfectly fine as long as no exception gets thrown. All statements within the try block will get executed, and the resource gets closed. The problem is when an exception occurs within a try block and you might not reach the end of the try block. And as a result, you will not close the resources. You should, therefore, put all your clean up code into the finally block or use a try-with-resources statement.

4. Never catch a Throwable class

Well, its one step more serious trouble. Because java errors are also subclasses of the Throwable. Errors are irreversible conditions that cannot be handled by JVM itself. And for some JVM implementations, JVM might not actually even invoke your catch clause on an Error.

6. Catch the most specific exception first

Most IDEs help you with this best practice. They report an unreachable code block when you try to catch the less specific exception first.

You can see an example of such a try-catch statement in the following code snippet. The first catch block handles all NumberFormatExceptions and the second one all IllegalArgumentExceptions which are not a NumberFormatException.

8. Never throw any exception from finally block

This is fine, as long as cleanUp() can never throw an exception. In the above example, if someMethod() throws an exception, and in the finally block also, cleanUp() throws an exception, that second exception will come out of the method and the original first exception (correct reason) will be lost forever. If the code that you call in a finally block can possibly throw an exception, make sure that you either handle it or log it. Never let it come out of the finally block.

9. Don’t use printStackTrace() statement or similar methods

Never leave printStackTrace() after finishing your code. Chances are one of your fellow colleagues will get one of those stack traces eventually, and have exactly zero knowledge as to what to do with it because it will not have any contextual information appended to it.

10. Use finally blocks instead of catch blocks if you are not going to handle the exception

This is also a good practice. If inside your method you are accessing some method 2, and method 2 throw some exception which you do not want to handle in method 1 but still want some cleanup in case exception to occur, then do this cleanup in finally block. Do not use catch block.

11. Validate user input to catch adverse conditions very early in request processing

Always validate user input in a very early stage, even before it reached to the actual controller. It will help you to minimize the exception handling code in your core application logic. It also helps you in making application consistent if there is some error in user input. Example:

12. Throw Exceptions With Descriptive Messages

java.lang.NumberFormatException:For input string:"xyz"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Long.parseLong(Long.java:589)
at java.lang.Long.<init>(Long.java:965)