UncheckedIOException and suppressed exception

Joseph Darcy joe.darcy at oracle.com
Mon Feb 4 18:11:21 PST 2013

On 2/4/2013 5:56 PM, David Holmes wrote:
> On 5/02/2013 10:16 AM, Zhong Yu wrote:
>> Suppose we have an UncheckedIOException e1, which wraps an IOException
>> e2. Then another exception e3 occurs that we want suppress. Should we
>> do e1.addSuppressed(e3), or e2.addSuppressed(e3)? That's pretty
>> confusing.
> I don't see any confusion except for your numbering. You have one
> exception that is inflight, e1, and then e3 occurs. If you want to
> continue throwing e1 then e1 is suppressing e3.
>> If UncheckedIOException is not a *real* exception, maybe we should
>> make it a "control" exception. It should have no stacktrace; it should
>> have no cause (the wrapped exception is not a cause); it should not
>> contain suppressed exceptions.
> Any wrapping exception should have the original exception as its cause.
> Why should this wrapper be any different? Throwable even defines it so:
> " Throwing a "wrapped exception" (i.e., an exception containing a cause)
> ..."
> Suppression is about control over which exception is propagating - so
> again why should this be a special case?
>> Maybe it can override addSuppressed() to forward suppressed exceptions
>> to the wrapped exception. (Though addSuppressed() is `final`, there's
>> no problem to leave a backdoor for another JDK class)
> I think your exception processing model is slightly confused here.

As an addendum, the Throwable.addSuppressed method discusses the 
difference between exception suppression and caused-by linkage:

> Note that when one exception causes another exception, the first 
> exception is usually caught and then the second exception is thrown in 
> response. In other words, there is a causal connection between the two 
> exceptions. In contrast, there are situations where two independent 
> exceptions can be thrown in sibling code blocks, in particular in the 
> try block of a try-with-resources statement and the compiler-generated 
> finally block which closes the resource. In these situations, only one 
> of the thrown exceptions can be propagated. In the try-with-resources 
> statement, when there are two such exceptions, the exception 
> originating from the try block is propagated and the exception from 
> the finally block is added to the list of exceptions suppressed by the 
> exception from the try block. As an exception unwinds the stack, it 
> can accumulate multiple suppressed exceptions.
> An exception may have suppressed exceptions while also being caused by 
> another exception. Whether or not an exception has a cause is 
> semantically known at the time of its creation, unlike whether or not 
> an exception will suppress other exceptions which is typically only 
> determined after an exception is thrown. 


More information about the lambda-dev mailing list