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.

Reply via email to