Thursday 16 July 2015

Disappearing Exceptions

Quoting from [1]:
If the catch block completes abruptly for reason R, then the finally block is executed. Then there is a choice:

If the finally block completes normally, then the try statement completes abruptly for reason R.

If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).
(Emphasis mine)

Conclusion

It is unwise to NOT catch Exceptions or throw Exceptions in a Finally block. An exception that is thrown in the finally block, may cause an exception in the try to be discarded. This can lead to errors that obscure the original error.

I can imagine how easy this can happen, for example, if there is an Exception in the try in such a fashion that the closing of resources in the Finally clause will also throw an Exception.

In fact, that is what happened at work, and threw me for a loop when attempting to debug.

Addendum

Luckily, with Java 72, when using the try-with-resources statement, this problem belongs to the past. Of course this only belongs to the past, if your try-catch-finally can be replaced with a try-with-resources.

To be specific, when using try-with-resources only the exception in the try is thrown. Subsequent exceptions, caused by the closing of the resources, are suppressed. But even these exceptions can still be recovered, by requesting all suppressed exceptions from the exception thrown in the try block3.

(Addendum added: 23 july 2015)

References

[1] JLS - 14.20.2. Execution of try-finally and try-catch-finally
http://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.20.2
[2] The Java™ Tutorials - The try-with-resources Statement
https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
[3] JavaDoc - Throwable.getSupressed()
http://docs.oracle.com/javase/8/docs/api/java/lang/Throwable.html#getSuppressed--

No comments:

Post a Comment