Java Exception handling best practices
Handling Java exceptions can be tricky.
Which Java exceptions should you catch, and which exceptions should you rethrow? And which exceptions can you ignore completely? This is a difficult skill to develop.
These Java Exception handling best practices provide software developers guidance when they develop new applications.
Top 10 Java Exception handling best practices
Here are the top 20 Java exception handling best practices software developers should follow:
- Be careful what you log.
- Don’t bury thrown exceptions.
- Use a global Exception handler.
- Don’t close resources manually.
- Throw early and handle exceptions late.
- Don’t log and rethrow Java exceptions.
- Check for suppressed exceptions.
- Explicitly define exception in the throws clause.
- Catch the most explicit exception first.
- Use modern exception handling semantics.
Be careful what you log
Software developers must always be mindful of the customer’s security and privacy rights.
One can move data logged by a Java application to various low-cost storage system, to be viewed by developers and administrators as they attempt to solve a bug.
However, you must ensure no protected data is written in the log files. Otherwise, your company will be out of compliance, and you might be out of a job.
Don’t bury thrown exceptions
Don’t catch an exception and then do nothing with it. That’s known as burying an exception, and it is definitely not a Java exception handling best practice.
At the very least, log the name of the exception and the message associated with it. That way you or others can extract information about an exceptional situation from the logs.
Buried exceptions makes troubleshooting Java applications extremely hard.
Use a global Exception handler
There will always be uncaught RuntimeExceptions that creep into your code.
Always include a global Exception handler to deal with any uncaught exceptions. This will not only enable you to log and potentially handle the Exception, but it will also stop your app from crashing when a runtime exception is thrown.
Don’t close resources manually
Another important Java exception handling best practice is to allow the JVM to call the close()
method of closeable resources. Don’t close resources yourself.
This is easily accomplished if you initialize resources within a try-with-resources block. The following example shows the try-with-resources semantics in action:
public class TryWithResourcesExample { public static void main(String[] args) throws Exception { try (Door door = new Door()) { door.swing(); } catch (Exception e) { /* do something */ } } finally { /* do something */ } /* The door will automatically be closed after the code block */ } }
The JVM closes the resource for you when the try…catch block completes. This eliminates the potential for messy and difficult-to-troubleshoot resource leaks.
Throw early and handle exceptions late
As soon as an exception condition happens in your code, throw an Exception. Don’t wait for any additional lines of code to run before you terminate execution of the method you are in.
The function to catch exceptions should go toward the end of a method. This puts fewer catch blocks in your methods, and makes your code much easier to read and maintain.
Don’t log and rethrow
When an Exception occurs you should either:
- log the Exception and carry on with your application; or
- rethrow the Exception and let another method log the details
Never do both. You should never log and then rethrow the same exception, as is done in the following example:
/* log and rethrow exception example */
try {
Class.forName("com.mcnz.Example");
} catch (ClassNotFoundException ex) {
log.warning("Class was not found.");
throw ex;
}
Doing so causes code duplication, and litters the log files with duplicate entries which makes it much more difficult to troubleshoot code.
Check for suppressed exceptions
The suppressed exception is a relatively new language feature that not all developers are aware of.
Basically, the introduction of the try-with-resources function, made it possible to throw two exceptions at the same time. You can easily check this situation simply by querying for the suppressed exception’s existence, as is done in the example below:
try ( Door door = new Door() ) {
door.swing(); /* Throws the SwingException */
}
catch (Exception e) {
System.out.println("Primary Exception: " + e.getClass());
if (e.getSuppressed().length > 0) {
System.out.print("Suppressed Exception: " + e.getSuppressed()[0]);
}
}
The only way to know if this scenario has occurred is to check if the target Exception also contains a suppressed exception.
Explicitly define exceptions in the throws clause
Lazy developers use the generic Exception class in the throws clause of a method. Doing so is not a Java exception handling best practice.
Instead, always explicitly state the exact set of exception a given method might throw. This allows other developers to know the various error handling routines they can employ if a given method fails to execute properly.
Catch the most specific exception first
This is more of a compiler requirement than a Java exception handling best practice, but a developer should always catch the most specific exception first, and the least specific one last.
If this rule is not followed, the JVM will generate a compile time error with a fairly cryptic error message that is difficult to understand.
Make your software development life easier, and always catch the most specific exception in your code first.
Use modern exception handling techniques
Is Java verbose? It is if you stick with the 20-year-old exception handling techniques.
Java has added many features around error and exception handling that simplify development and greatly reduce the verbosity of Java code.
Take advantage of the ability to catch multiple exceptions in a single catch block, automatically close resource with the try-with-resources block, and use RuntimeExceptions so other developers aren’t forced to handle the exceptions you throw.
Follow these 10 Java exception handling best practices, and you’ll find yourself learning to love dealing with exceptions in Java.