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