Andrei Alexandrescu Wrote:

> Consider:
> 
> void fun() {
>     try {
>        throw new Exception("a");
>     } finally {
>        throw new Exception("b");
>     }
> }
> 
> Currently this function would unceremoniously terminate the program. I 
> think it shouldn't.

Have you tried it?  I think the call to terminate() is commented out.  It was 
like this before I ever started mucking with the runtime many moons ago.  What 
I think currently happens is that the exception in the finally clause will 
replace the one being thrown.  That or it's discarded, I really can't remember 
which.  Either way, the current behavior is a bit weird.

> What should happen is that the "a" exception should 
> be propagated unabated, and the "b" exception should be appended to it. 
> The Exception class should have a property "next" that returns a 
> reference to the next exception thrown (in this case "b"), effectively 
> establishing an arbitrarily long singly-linked list of exceptions.

The Exception class already has a "next" property, but I've always seen this as 
a way to nest exceptions.  For example:

try
{
    throw new Exception;
}
catch( Exception e )
{
    throw new MyException( e );
}

So a network API might throw a NetworkException that references a 
SocketException with more detailed info about the exact problem, etc.  The 
reason I'm unsure about chaining related exceptions as opposed to use chaining 
as a means of repackaging exceptions is that the catch handler that ultimately 
executes will be the one that matches the first exception in the chain, not the 
first that matches any exception in the chain.  I haven't thought about this 
too carefully, but it seems like it might be difficult to write correct code 
with this model.

> A friend told me that that's what Java does, with the difference that 
> the last exception thrown takes over, so the chain comes reversed. I 
> strongly believe "a" is the main exception and "b" is a contingent 
> exception, so we shouldn't do what Java does. But Java must have some 
> good reason to go the other way.

When a dozen holes appear in a dike, I'm not sure it matters which one you try 
to plug first :-)  Unless there's some way to start with the biggest one, I 
suppose.  Seems like with the suggested model, the correct approach may be to 
always catch Exception and walk the whole chain to figure out what to do.  But 
that sounds awfully close to C-style error handling.  

Reply via email to