Suppressed Exceptions
The program output from GizmoTest in Example 7.18 shows that the Arithmetic-Exception was thrown in the compute() method called in the try block at (4) before the IllegalArgumentException was thrown by the implicit call to the close() method. Since only one exception can be propagated, the IllegalArgumentException thrown last would mask the ArithmeticException and the IllegalArgumentException would be propagated. However, the stack trace shows that this is not the case.
Exceptions thrown from the body of a try-with-resources statement are given preferential treatment over exceptions thrown by the close() method when called implicitly to close a declared resource. Exceptions thrown in the try block pertain to the program logic and should not be masked, but at the same time any exceptions thrown in the close() method should not be ignored. A solution is provided through suppressed exceptions. The class Throwable provides the following methods to handle such exceptions:
void addSuppressed(Throwable exception)
Appends the specified exception to the exceptions that were suppressed in order to deliver this exception.
Throwable[] getSuppressed()
Returns an array containing all of the exceptions that were suppressed in order to deliver this exception.
An exception s that is associated with an exception e through the method call e.addSuppressed(s) is called a suppressed exception. The idea is that if exception s was thrown during the propagation of exception e, then exception s is suppressed and the propagation of exception e continues. When exception e is caught, it is possible to retrieve all its suppressed exceptions by the method call e.getSuppressed().
From the stack trace printed by GizmoTest in Example 7.18, we see that the IllegalArgumentException was thrown in the close() method and is implicitly associated with the ArithmeticException that was thrown earlier in the compute() method—that is, the IllegalArgumentException was suppressed and the ArithmeticException was propagated.
In the catch clause at (6) of GizmoTest2 in Example 7.18, the exception thrown and the suppressed exception are printed explicitly. The method call ex.getSuppressed() at (7) returns an array of Throwable containing the suppressed IllegalArgument-Exception. Of course, suppressing any exception from the close() method is only warranted if an exception is thrown in the body of the try-with-resources statement. The compiler expands the try-with-resources statement into code (essentially a combination of basic try-catch-finally blocks with the necessary control flow) that ensures proper closing of the declared resources, and handling of suppressed exce
Leave a Reply