Exception chaining

monarch_dodra monarchdodra at gmail.com
Sat Sep 14 07:49:21 PDT 2013


On Friday, 13 September 2013 at 23:58:33 UTC, Sean Kelly wrote:
> Exception chaining is actually built-in.  I did some digging 
> for an official description, but couldn't find one.  Here's a 
> summary:
>
> If an Exception is thrown when an Exception or Error is already 
> in flight, it is considered collateral damage and appended to 
> the chain (built via Throwable.next).
>
> If an Error is thrown when an Exception is already in flight, 
> it will replace the in flight Exception and reference it via 
> Error.bypassedException.
>
> If an Error is thrown when an Error is already in flight, it 
> will be considered collateral damage and appended to the 
> Throwable.next chain.

Hum. The problem here, is the concept of "in flight". It implies 
an exception is *currently* going up, and that the exceptions 
thrown come from automatically called destructor (or functions 
called by destructor).

My problem though, is that I am already in an exception handling 
"block", so there is no "in flight" exception, just the exception 
that's in my handle. Here is a reduced pseudo code of what I 
have, where "doThem" needs to do "doIt" "n" times, but needs to 
"unDoIt" if an exception is thrown. My code looks like this:

//--------
void doThem(size_t n)
{
     size_t i;
     try
     {
         for ( ; i < n ; ++i)
             doIt(i);
     }
     catch (Exception e)
     {
         //Grab the tail.
         Throwable tail = e;
         while(tail.next !is null)
             tail = tail.next;

         try //Start cleaning up
         {

             //undo everything individually
             for ( --i ; i < n ; --i)
             {
                 try
                     unDoIt(i); //This is the actual call
                 catch (Exception ee)
                     tail = (tail.next = ee);
             }
         }
         catch (Error ee) //An Error!
         {
             //insert the current exception before the currently 
bypassed exceptions.
             tail = ee.bypassedException;
             ee.bypassedException = e;
             throw ee;
         }
     }
}
//--------

I think this is crazy.

The two questions I have are:
1. Am I doing it right?
2. Should I even bother? Even dmd doesn't bother printing the 
chained exceptions on death.

I mean, my code could just as well be:
//----
void doThem(size_t n)
{
     size_t i;
     try
     {
         for ( ; i < n ; ++i)
             doIt(i);
     }
     catch (Exception e)
     {
         for ( --i ; i < n ; --i)
         {
             try
                 unDoIt(i);
             catch (Exception /+ee+/)
             {/+ignore ee+/}
         }
     }
}
//----

Much simpler!

For a bit of context, the code I have in mind is static array 
postblit: Postblit each element. If this fails, then destroy all 
previously post-blitted elements.


More information about the Digitalmars-d-learn mailing list