Hello guys, I am back with the new blog and in this blog, we will discuss best practices to handle exceptions. Let us get started…
- Cleaning Up Resources in the Finally Block
If you use any resource for example InputStream, it is very important to release the resource or close the resource. If you don’t, you might end up utilizing the resource indefinitely (Memory leak). The best way to handle this situation is to release the resource in the finally block. As you all know, finally block is executed no matter what exception occurs or not.
In the above program, I have used InputStream and I have closed it in the finally block. One small drawback in finally block is that you might end up performing null checks before closing any resource. That might lead to cluttered coding.
As an alternate, you can use the next approach which is try-with-resource.
In this approach, you don’t have to provide an explicit finally block. The JVM closes all the resources automatically provided the resource class implements the AutoCloseable interface.
Let us use the above program with try-with-resource
The above code looks much cleaner and the resource is auto closed by the JVM.
Now let us define our own resource and then use it in try-with-resource.
As you can see, the close method is called automatically by the JVM.
3. Prefer Specific Exceptions
Always provide a specific exception than the generic one. For example, if I am using a method from a third party library and it is throwing a generic exception, I would not come to know about what kind of problem I could face. But if it throws a specific exception such as IOException or SQLException then I know that I am dealing with I/O operations or some SQL query related operations. Let us see an example of throwing a specific exception.
4. Document the Exception You Specify
It is very important to document the exception as it provides the caller some significant information required to handle the exception.
5. Throw Exceptions with Descriptive Messages
The exception’s message gets read by everyone who has to understand what had happened when the exception was reported in the log file or your monitoring tool. It should, therefore, describe the problem as precisely as possible and provide the most relevant information to understand the exceptional event. This helps to understand the severity of the problem.
6. Catch the Most Specific Information First
Most modern IDE’s help you with the best practices such as they report an unreachable code block when you try to catch the less specific exception first.
For example, if you catch an IllegalArgumentException first, you will never reach the catch block that should handle more specific NumberFormatException because it is a subclass of the IllegalArgumentException. So it is very much important to catch the most specific ones first followed by the least specific ones.
7. Don’t Catch Throwable
Throwable is the superclass of all exceptions and errors. If you use throwable in the catch clause, it will not only catch all exceptions but it will catch all errors as well. Errors are thrown by the JVM to indicate serious problems that are not intended to be handled by an application. For example — OutofMemoryError or StackOverFlowError. Both are caused by situations that are outside of the control of the application. So never catch a Throwable unless you are absolutely sure that you are in an exceptional situation.
8. Never Ignore Exceptions
I have seen codes where the catch block is empty. The developer is pretty sure that exception will never occur. Well, there are chances that you might end up analyzing the problem in which the unexpected happened. So, it is better to never ignore exceptions and there are chances that code might get changed in the future.
9. Don’t Log and Throw
Again, there are a lot of code snippets and even libraries in which an exception gets caught, logged, and rethrown. It might feel intuitive to log an exception when it occurred and then rethrow it so that the caller can handle it appropriately. But it will write multiple error messages for the same exception. So, it is better to throw the exception and let the caller decide on how to handle the exception.
10. Wrap the Exception Without Consuming it
It is sometimes better to catch a standard exception and wrap it into the custom one. A typical example of such an exception is an application or framework-specific business exception. That allows you to add additional information and you can also implement special handling for your exception class. When you do that, make sure to add the original exception as the cause. The Exception class provides a specific constructor method that accepts a Throwable as a parameter. Otherwise, you lose the stack trace and message of the original exception which will make it difficult to analyze the exceptional event that caused your exception.
I hope you guys understood the best practices for handling exceptions. That's it from this blog.