January 11, 2011
On 1/11/11 4:03 PM, Jonathan M Davis wrote:
> On Tuesday, January 11, 2011 15:50:52 Andrei Alexandrescu wrote:
>> I don't think that's helpful. It complicates the flow a lot because now understanding how the program acts depends not on the types anymore, but on what happens dynamically. Makes it more difficult, not easier, to write robust code.
>>
>> If I throw a FileException, I must catch a FileException with catch(FileException) regardless of what collateral exceptions have happened.
>
> I agree as long as it's other Exceptions that have been thrown. But Errors? Aren't they typically supposed to kill your program?
>
> - Jonathan M Davis

I agree that non-Exception Throwables are an out-of-band method of communication that deserves special attention.

Don, would it be difficult to make a non-Exception Throwable thrown during unwinding essentially come to the top of the foodchain and save everything in its tail?


Andrei
January 12, 2011
On 12 January 2011 01:10, Andrei Alexandrescu <andrei at erdani.com> wrote:
> On 1/11/11 4:03 PM, Jonathan M Davis wrote:
>>
>> On Tuesday, January 11, 2011 15:50:52 Andrei Alexandrescu wrote:
>>>
>>> I don't think that's helpful. It complicates the flow a lot because now understanding how the program acts depends not on the types anymore, but on what happens dynamically. Makes it more difficult, not easier, to write robust code.
>>>
>>> If I throw a FileException, I must catch a FileException with catch(FileException) regardless of what collateral exceptions have happened.
>>
>> I agree as long as it's other Exceptions that have been thrown. But
>> Errors?
>> Aren't they typically supposed to kill your program?
>>
>> - Jonathan M Davis
>
> I agree that non-Exception Throwables are an out-of-band method of communication that deserves special attention.
>
> Don, would it be difficult to make a non-Exception Throwable thrown during unwinding essentially come to the top of the foodchain and save everything in its tail?

It wouldn't be difficult. The difficult thing would be to make a rule
that's sensible and uncomplicated.
The exception handler receives a list of exception records, some of
which are Errors and some are Exceptions,
and it has to determine if a given Object can catch that list.

The chain of D objects is created only when we know we've caught them, so it can be constructed in any order.
January 12, 2011
How about this rule:
---
If all collateral exceptions are derived from Exception, the 'boss' or
Master Exception is the first exception thrown.
Otherwise, the first Error (or Throwable non-Exception) is the boss.
The exception, including all collateral exceptions, will be caught by
the first handler who can catch the boss.
---

Two issues:
* If the boss is a collateral exception, we still need a way to find
out what the first exception was. Maybe need to add a 'first' (or
'prev') member to Throwable?
* It is still possible to throw an Object which isn't derived from
Throwable. Can we disallow this?
(We could throw a "NoThrowableError" if such an object is found to
have been thrown (can happen via casting)). This would remove some
really nasty corner cases.


On 12 January 2011 01:10, Andrei Alexandrescu <andrei at erdani.com> wrote:
> On 1/11/11 4:03 PM, Jonathan M Davis wrote:
>>
>> On Tuesday, January 11, 2011 15:50:52 Andrei Alexandrescu wrote:
>>>
>>> I don't think that's helpful. It complicates the flow a lot because now understanding how the program acts depends not on the types anymore, but on what happens dynamically. Makes it more difficult, not easier, to write robust code.
>>>
>>> If I throw a FileException, I must catch a FileException with catch(FileException) regardless of what collateral exceptions have happened.
>>
>> I agree as long as it's other Exceptions that have been thrown. But
>> Errors?
>> Aren't they typically supposed to kill your program?
>>
>> - Jonathan M Davis
>
> I agree that non-Exception Throwables are an out-of-band method of communication that deserves special attention.
>
> Don, would it be difficult to make a non-Exception Throwable thrown during unwinding essentially come to the top of the foodchain and save everything in its tail?
>
>
> Andrei
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
>
January 12, 2011
On Wednesday 12 January 2011 00:10:59 Don Clugston wrote:
> * It is still possible to throw an Object which isn't derived from Throwable. Can we disallow this?

I don't understand why it was ever allowed. Permitting you to throw something not derived from a common exception class seems incredibly stupid. I hate the fact that C++ does it, and I was surprised when I learned that D propagated the mistake. And especially since we pretty much seem to act like everything which is thrown is derived from Throwable, I don't see why it isn't actually the case. The Throwable, Exception, Error hierarchy makes sense. Allowing someone to throw ints or strings or whatnot doesn't.

- Jonathan M Davis
January 12, 2011
Will one be able to replace exceptions? A common C# scenario:

class SystemException : Exception
{
    this(string msg, Exception innerEx) { this(msg, innerEx); }
}

class SubsystemException : Exception
{
     this(string msg) { this(msg); }
}

void system()
{
    try
    {
         subsystem();
    }
    catch (SubsystemException ex)
    {
        // subsystem exception is replaced with system exception and linked
to the latter
        throw new SystemException("a system exception", ex);
    }
}

void subsystem()
{
    throw new SubsystemException("a subsystem exception");
}

void main()
{
      try
      {
          system();
      }
      catch (SystemException ex)
      {
           // catch system exceptions and subsystem exceptions are available
via innerException property
           writeln("system: ", ex, ", subsystem: ", ex.innerException);

      }
}

As far as I understand, your scheme makes the above problematic.

On Wed, Jan 12, 2011 at 1:50 AM, Andrei Alexandrescu <andrei at erdani.com>wrote:

> I don't think that's helpful. It complicates the flow a lot because now understanding how the program acts depends not on the types anymore, but on what happens dynamically. Makes it more difficult, not easier, to write robust code.
>
> If I throw a FileException, I must catch a FileException with catch(FileException) regardless of what collateral exceptions have happened.
>
>
> Andrei
>
>
> On 1/11/11 12:31 PM, Don Clugston wrote:
>
>> I've thought about this a bit more. Another simple rule is, that an
>> exception chain can be caught if  and only if every exception in that
>> chain can be caught.
>> So, for example,
>> catch(FileException) will catch multiple file exceptions.
>> catch(Exception) will catch any exception (but not Errors).
>> catch(Throwable) catches Errors as well.
>>
>> I went ahead and implemented this. Everythings seems to Just Work. Will check it in shortly.
>>
>>
>> On 11 January 2011 18:30, Andrei Alexandrescu<andrei at erdani.com>  wrote:
>>
>>> Wow, this is incredible news!
>>>
>>> Thanks Don for working on this. Solid exception handling is a huge
>>> selling
>>> point for D.
>>>
>>> Regarding collateral throwables that are not Exception, good point (and I
>>> agree that the solution should be simple). TDPL doesn't discuss that
>>> issue,
>>> but it says that the initially-thrown exception is the "boss" and that
>>> everybody follows, so a possible design is to simply make the Throwable
>>> part
>>> of the chain.
>>>
>>> I'd want to have chained exceptions still catchable by catch (Exception)
>>> because it would be a first to have the contents of the data influence
>>> its
>>> type. As far as the type system is concerned, catch (Exception) should
>>> catch
>>> Exceptions, whether or not they have a tail.
>>>
>>> One possibility would be to move the Throwable to the front of the list.
>>> This also has its issues, for example the stack is unwound for a while
>>> and
>>> then not anymore (a Throwable is allowed to respect fewer rules than an
>>> Exception).
>>>
>>> Ideas please?
>>>
>>>
>>> Andrei
>>>
>>> On 1/11/11 1:57 AM, Don Clugston wrote:
>>>
>>>>
>>>> I believe I have got TDPL exception chaining working correctly using
>>>> Windows Structured Exception Handling.
>>>> (This was far from easy!)
>>>> Central to making chaining work correctly, is that chaining must only
>>>> occur
>>>> when a collision occurs (not merely when two exceptions are in flight,
>>>> because one may be caught before it has any effect on the other). This
>>>> means that multiple chains of exceptions
>>>> may be in flight at any given time.
>>>> My code works in all nasty corner cases I've tested, including
>>>> multi-level collisions,
>>>> where two exceptions collide in a function, then collide again with an
>>>> even earlier exception chain in a finally block in a different function.
>>>>
>>>> So the general scheme appears to work.
>>>> But, there's something I'm unclear about. When should chained
>>>> exceptions be catchable?
>>>> They are very nasty creatures, and you really want to know when they
>>>> happen.
>>>> Presumably, an AssertError which occurs while processing an
>>>> FileException, should not be silently chained
>>>> and caught in the FileException.
>>>> In fact, should a chain containing an Error be catchable at all?
>>>> (If not, it still has to at least be catchable in the catchall handler
>>>> that wraps main()).
>>>> Many other schemes are possible, but I think it's important that the
>>>> rules remain simple.
>>>>
>>>> One simple solution would be to make chained exceptions only catchable
>>>> by catch(Throwable).
>>>> _______________________________________________
>>>> phobos mailing list
>>>> phobos at puremagic.com
>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>>
>>>
>>> _______________________________________________
>>> phobos mailing list
>>> phobos at puremagic.com
>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>
>>>  _______________________________________________
>> phobos mailing list
>> phobos at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/phobos
>>
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/phobos/attachments/20110112/840b1b56/attachment.html>
January 12, 2011
No, that's unaffected by the scheme. The scheme only affects situations when an exception is thrown from inside a finally clause, when the finally clause is being executed because an exception had been thrown. It doesn't affect catch clauses, because once you're inside the catch, the first exception is no longer in flight.


On 12 January 2011 09:27, Max Samukha <maxsamukha at gmail.com> wrote:
> Will one be able to replace exceptions? A common C# scenario:
>
> class SystemException : Exception
> {
> ??? this(string msg, Exception innerEx) { this(msg, innerEx); }
> }
>
> class SubsystemException : Exception
> {
> ???? this(string msg) { this(msg); }
> }
>
> void system()
> {
> ? ? try
> ? ? {
> ???????? subsystem();
> ? ? }
> ??? catch (SubsystemException ex)
> ? ? {
> ??????? // subsystem exception is replaced with system exception and linked
> to the latter
> ??????? throw new SystemException("a system exception", ex);
> ??? }
> }
>
> void subsystem()
> {
> ??? throw new SubsystemException("a subsystem exception");
> }
>
> void main()
> {
> ? ? ? try
> ? ? ? {
> ????????? system();
> ????? }
> ????? catch (SystemException ex)
> ? ??? {
> ?????????? // catch system exceptions and subsystem exceptions are available
> via innerException property
> ?????????? writeln("system: ", ex, ", subsystem: ", ex.innerException);
>
> ? ? ? }
> }
>
> As far as I understand, your scheme makes the above problematic.
>
> On Wed, Jan 12, 2011 at 1:50 AM, Andrei Alexandrescu <andrei at erdani.com> wrote:
>>
>> I don't think that's helpful. It complicates the flow a lot because now understanding how the program acts depends not on the types anymore, but on what happens dynamically. Makes it more difficult, not easier, to write robust code.
>>
>> If I throw a FileException, I must catch a FileException with catch(FileException) regardless of what collateral exceptions have happened.
>>
>>
>> Andrei
>>
>> On 1/11/11 12:31 PM, Don Clugston wrote:
>>>
>>> I've thought about this a bit more. Another simple rule is, that an
>>> exception chain can be caught if ?and only if every exception in that
>>> chain can be caught.
>>> So, for example,
>>> catch(FileException) will catch multiple file exceptions.
>>> catch(Exception) will catch any exception (but not Errors).
>>> catch(Throwable) catches Errors as well.
>>>
>>> I went ahead and implemented this. Everythings seems to Just Work. Will check it in shortly.
>>>
>>>
>>> On 11 January 2011 18:30, Andrei Alexandrescu<andrei at erdani.com> ?wrote:
>>>>
>>>> Wow, this is incredible news!
>>>>
>>>> Thanks Don for working on this. Solid exception handling is a huge
>>>> selling
>>>> point for D.
>>>>
>>>> Regarding collateral throwables that are not Exception, good point (and
>>>> I
>>>> agree that the solution should be simple). TDPL doesn't discuss that
>>>> issue,
>>>> but it says that the initially-thrown exception is the "boss" and that
>>>> everybody follows, so a possible design is to simply make the Throwable
>>>> part
>>>> of the chain.
>>>>
>>>> I'd want to have chained exceptions still catchable by catch (Exception)
>>>> because it would be a first to have the contents of the data influence
>>>> its
>>>> type. As far as the type system is concerned, catch (Exception) should
>>>> catch
>>>> Exceptions, whether or not they have a tail.
>>>>
>>>> One possibility would be to move the Throwable to the front of the list.
>>>> This also has its issues, for example the stack is unwound for a while
>>>> and
>>>> then not anymore (a Throwable is allowed to respect fewer rules than an
>>>> Exception).
>>>>
>>>> Ideas please?
>>>>
>>>>
>>>> Andrei
>>>>
>>>> On 1/11/11 1:57 AM, Don Clugston wrote:
>>>>>
>>>>> I believe I have got TDPL exception chaining working correctly using
>>>>> Windows Structured Exception Handling.
>>>>> (This was far from easy!)
>>>>> Central to making chaining work correctly, is that chaining must only
>>>>> occur
>>>>> when a collision occurs (not merely when two exceptions are in flight,
>>>>> because one may be caught before it has any effect on the other). This
>>>>> means that multiple chains of exceptions
>>>>> may be in flight at any given time.
>>>>> My code works in all nasty corner cases I've tested, including
>>>>> multi-level collisions,
>>>>> where two exceptions collide in a function, then collide again with an
>>>>> even earlier exception chain in a finally block in a different
>>>>> function.
>>>>>
>>>>> So the general scheme appears to work.
>>>>> But, there's something I'm unclear about. When should chained
>>>>> exceptions be catchable?
>>>>> They are very nasty creatures, and you really want to know when they
>>>>> happen.
>>>>> Presumably, an AssertError which occurs while processing an
>>>>> FileException, should not be silently chained
>>>>> and caught in the FileException.
>>>>> In fact, should a chain containing an Error be catchable at all?
>>>>> (If not, it still has to at least be catchable in the catchall handler
>>>>> that wraps main()).
>>>>> Many other schemes are possible, but I think it's important that the
>>>>> rules remain simple.
>>>>>
>>>>> One simple solution would be to make chained exceptions only catchable
>>>>> by catch(Throwable).
>>>>> _______________________________________________
>>>>> phobos mailing list
>>>>> phobos at puremagic.com
>>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>>
>>>> _______________________________________________
>>>> phobos mailing list
>>>> phobos at puremagic.com
>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>>
>>> _______________________________________________
>>> phobos mailing list
>>> phobos at puremagic.com
>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>
>> _______________________________________________
>> phobos mailing list
>> phobos at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/phobos
>
>
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
>
January 12, 2011
On 12 January 2011 09:10, Don Clugston <dclugston at googlemail.com> wrote:
> How about this rule:
> ---
> If all collateral exceptions are derived from Exception, the 'boss' or
> Master Exception is the first exception thrown.
> Otherwise, the first Error (or Throwable non-Exception) is the boss.
> The exception, including all collateral exceptions, will be caught by
> the first handler who can catch the boss.
> ---
>
> Two issues:
> * If the boss is a collateral exception, we still need a way to find
> out what the first exception was. Maybe need to add a 'first' (or
> 'prev') member to Throwable?

Or, the chain could simply be:
boss -> exception1 -> exception2 -> BypassThrowable -> exception3.

Where BypassThrowable is a class which acts as a placeholder for the boss.

This would be the simplest interim solution, since it doesn't require
any code changes elsewhere, and would allow the
existing error messages to continue to work correctly.


> * It is still possible to throw an Object which isn't derived from
> Throwable. Can we disallow this?
> (We could throw a "NoThrowableError" if such an object is found to
> have been thrown (can happen via casting)). This would remove some
> really nasty corner cases.
>
>
> On 12 January 2011 01:10, Andrei Alexandrescu <andrei at erdani.com> wrote:
>> On 1/11/11 4:03 PM, Jonathan M Davis wrote:
>>>
>>> On Tuesday, January 11, 2011 15:50:52 Andrei Alexandrescu wrote:
>>>>
>>>> I don't think that's helpful. It complicates the flow a lot because now understanding how the program acts depends not on the types anymore, but on what happens dynamically. Makes it more difficult, not easier, to write robust code.
>>>>
>>>> If I throw a FileException, I must catch a FileException with catch(FileException) regardless of what collateral exceptions have happened.
>>>
>>> I agree as long as it's other Exceptions that have been thrown. But
>>> Errors?
>>> Aren't they typically supposed to kill your program?
>>>
>>> - Jonathan M Davis
>>
>> I agree that non-Exception Throwables are an out-of-band method of communication that deserves special attention.
>>
>> Don, would it be difficult to make a non-Exception Throwable thrown during unwinding essentially come to the top of the foodchain and save everything in its tail?
>>
>>
>> Andrei
>> _______________________________________________
>> phobos mailing list
>> phobos at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/phobos
>>
>
January 12, 2011
Thanks, Don. Looks like I completely missed the point of the discussion.

On Wed, Jan 12, 2011 at 10:46 AM, Don Clugston <dclugston at googlemail.com>wrote:

> No, that's unaffected by the scheme. The scheme only affects situations when an exception is thrown from inside a finally clause, when the finally clause is being executed because an exception had been thrown. It doesn't affect catch clauses, because once you're inside the catch, the first exception is no longer in flight.
>
>
> On 12 January 2011 09:27, Max Samukha <maxsamukha at gmail.com> wrote:
> > Will one be able to replace exceptions? A common C# scenario:
> >
> > class SystemException : Exception
> > {
> >     this(string msg, Exception innerEx) { this(msg, innerEx); }
> > }
> >
> > class SubsystemException : Exception
> > {
> >      this(string msg) { this(msg); }
> > }
> >
> > void system()
> > {
> >     try
> >     {
> >          subsystem();
> >     }
> >     catch (SubsystemException ex)
> >     {
> >         // subsystem exception is replaced with system exception and
> linked
> > to the latter
> >         throw new SystemException("a system exception", ex);
> >     }
> > }
> >
> > void subsystem()
> > {
> >     throw new SubsystemException("a subsystem exception");
> > }
> >
> > void main()
> > {
> >       try
> >       {
> >           system();
> >       }
> >       catch (SystemException ex)
> >       {
> >            // catch system exceptions and subsystem exceptions are
> available
> > via innerException property
> >            writeln("system: ", ex, ", subsystem: ", ex.innerException);
> >
> >       }
> > }
> >
> > As far as I understand, your scheme makes the above problematic.
> >
> > On Wed, Jan 12, 2011 at 1:50 AM, Andrei Alexandrescu <andrei at erdani.com> wrote:
> >>
> >> I don't think that's helpful. It complicates the flow a lot because now understanding how the program acts depends not on the types anymore, but
> on
> >> what happens dynamically. Makes it more difficult, not easier, to write robust code.
> >>
> >> If I throw a FileException, I must catch a FileException with catch(FileException) regardless of what collateral exceptions have
> happened.
> >>
> >>
> >> Andrei
> >>
> >> On 1/11/11 12:31 PM, Don Clugston wrote:
> >>>
> >>> I've thought about this a bit more. Another simple rule is, that an
> >>> exception chain can be caught if  and only if every exception in that
> >>> chain can be caught.
> >>> So, for example,
> >>> catch(FileException) will catch multiple file exceptions.
> >>> catch(Exception) will catch any exception (but not Errors).
> >>> catch(Throwable) catches Errors as well.
> >>>
> >>> I went ahead and implemented this. Everythings seems to Just Work. Will check it in shortly.
> >>>
> >>>
> >>> On 11 January 2011 18:30, Andrei Alexandrescu<andrei at erdani.com>
>  wrote:
> >>>>
> >>>> Wow, this is incredible news!
> >>>>
> >>>> Thanks Don for working on this. Solid exception handling is a huge
> >>>> selling
> >>>> point for D.
> >>>>
> >>>> Regarding collateral throwables that are not Exception, good point
> (and
> >>>> I
> >>>> agree that the solution should be simple). TDPL doesn't discuss that
> >>>> issue,
> >>>> but it says that the initially-thrown exception is the "boss" and that
> >>>> everybody follows, so a possible design is to simply make the
> Throwable
> >>>> part
> >>>> of the chain.
> >>>>
> >>>> I'd want to have chained exceptions still catchable by catch
> (Exception)
> >>>> because it would be a first to have the contents of the data influence
> >>>> its
> >>>> type. As far as the type system is concerned, catch (Exception) should
> >>>> catch
> >>>> Exceptions, whether or not they have a tail.
> >>>>
> >>>> One possibility would be to move the Throwable to the front of the
> list.
> >>>> This also has its issues, for example the stack is unwound for a while
> >>>> and
> >>>> then not anymore (a Throwable is allowed to respect fewer rules than
> an
> >>>> Exception).
> >>>>
> >>>> Ideas please?
> >>>>
> >>>>
> >>>> Andrei
> >>>>
> >>>> On 1/11/11 1:57 AM, Don Clugston wrote:
> >>>>>
> >>>>> I believe I have got TDPL exception chaining working correctly using
> >>>>> Windows Structured Exception Handling.
> >>>>> (This was far from easy!)
> >>>>> Central to making chaining work correctly, is that chaining must only
> >>>>> occur
> >>>>> when a collision occurs (not merely when two exceptions are in
> flight,
> >>>>> because one may be caught before it has any effect on the other).
> This
> >>>>> means that multiple chains of exceptions
> >>>>> may be in flight at any given time.
> >>>>> My code works in all nasty corner cases I've tested, including
> >>>>> multi-level collisions,
> >>>>> where two exceptions collide in a function, then collide again with
> an
> >>>>> even earlier exception chain in a finally block in a different function.
> >>>>>
> >>>>> So the general scheme appears to work.
> >>>>> But, there's something I'm unclear about. When should chained
> >>>>> exceptions be catchable?
> >>>>> They are very nasty creatures, and you really want to know when they
> >>>>> happen.
> >>>>> Presumably, an AssertError which occurs while processing an
> >>>>> FileException, should not be silently chained
> >>>>> and caught in the FileException.
> >>>>> In fact, should a chain containing an Error be catchable at all?
> >>>>> (If not, it still has to at least be catchable in the catchall
> handler
> >>>>> that wraps main()).
> >>>>> Many other schemes are possible, but I think it's important that the
> >>>>> rules remain simple.
> >>>>>
> >>>>> One simple solution would be to make chained exceptions only
> catchable
> >>>>> by catch(Throwable).
> >>>>> _______________________________________________
> >>>>> phobos mailing list
> >>>>> phobos at puremagic.com
> >>>>> http://lists.puremagic.com/mailman/listinfo/phobos
> >>>>
> >>>> _______________________________________________
> >>>> phobos mailing list
> >>>> phobos at puremagic.com
> >>>> http://lists.puremagic.com/mailman/listinfo/phobos
> >>>>
> >>> _______________________________________________
> >>> phobos mailing list
> >>> phobos at puremagic.com
> >>> http://lists.puremagic.com/mailman/listinfo/phobos
> >>
> >> _______________________________________________
> >> phobos mailing list
> >> phobos at puremagic.com
> >> http://lists.puremagic.com/mailman/listinfo/phobos
> >
> >
> > _______________________________________________
> > phobos mailing list
> > phobos at puremagic.com
> > http://lists.puremagic.com/mailman/listinfo/phobos
> >
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/phobos/attachments/20110112/7a1fe256/attachment.html>
January 12, 2011
I think scope(failure) may need some work though, since it's modeled as a catch block.

Sent from my iPhone

On Jan 12, 2011, at 12:46 AM, Don Clugston <dclugston at googlemail.com> wrote:

> No, that's unaffected by the scheme. The scheme only affects situations when an exception is thrown from inside a finally clause, when the finally clause is being executed because an exception had been thrown. It doesn't affect catch clauses, because once you're inside the catch, the first exception is no longer in flight.
> 
> 
> On 12 January 2011 09:27, Max Samukha <maxsamukha at gmail.com> wrote:
>> Will one be able to replace exceptions? A common C# scenario:
>> 
>> class SystemException : Exception
>> {
>>     this(string msg, Exception innerEx) { this(msg, innerEx); }
>> }
>> 
>> class SubsystemException : Exception
>> {
>>      this(string msg) { this(msg); }
>> }
>> 
>> void system()
>> {
>>     try
>>     {
>>          subsystem();
>>     }
>>     catch (SubsystemException ex)
>>     {
>>         // subsystem exception is replaced with system exception and linked
>> to the latter
>>         throw new SystemException("a system exception", ex);
>>     }
>> }
>> 
>> void subsystem()
>> {
>>     throw new SubsystemException("a subsystem exception");
>> }
>> 
>> void main()
>> {
>>       try
>>       {
>>           system();
>>       }
>>       catch (SystemException ex)
>>       {
>>            // catch system exceptions and subsystem exceptions are available
>> via innerException property
>>            writeln("system: ", ex, ", subsystem: ", ex.innerException);
>> 
>>       }
>> }
>> 
>> As far as I understand, your scheme makes the above problematic.
>> 
>> On Wed, Jan 12, 2011 at 1:50 AM, Andrei Alexandrescu <andrei at erdani.com> wrote:
>>> 
>>> I don't think that's helpful. It complicates the flow a lot because now understanding how the program acts depends not on the types anymore, but on what happens dynamically. Makes it more difficult, not easier, to write robust code.
>>> 
>>> If I throw a FileException, I must catch a FileException with catch(FileException) regardless of what collateral exceptions have happened.
>>> 
>>> 
>>> Andrei
>>> 
>>> On 1/11/11 12:31 PM, Don Clugston wrote:
>>>> 
>>>> I've thought about this a bit more. Another simple rule is, that an
>>>> exception chain can be caught if  and only if every exception in that
>>>> chain can be caught.
>>>> So, for example,
>>>> catch(FileException) will catch multiple file exceptions.
>>>> catch(Exception) will catch any exception (but not Errors).
>>>> catch(Throwable) catches Errors as well.
>>>> 
>>>> I went ahead and implemented this. Everythings seems to Just Work. Will check it in shortly.
>>>> 
>>>> 
>>>> On 11 January 2011 18:30, Andrei Alexandrescu<andrei at erdani.com>  wrote:
>>>>> 
>>>>> Wow, this is incredible news!
>>>>> 
>>>>> Thanks Don for working on this. Solid exception handling is a huge
>>>>> selling
>>>>> point for D.
>>>>> 
>>>>> Regarding collateral throwables that are not Exception, good point (and
>>>>> I
>>>>> agree that the solution should be simple). TDPL doesn't discuss that
>>>>> issue,
>>>>> but it says that the initially-thrown exception is the "boss" and that
>>>>> everybody follows, so a possible design is to simply make the Throwable
>>>>> part
>>>>> of the chain.
>>>>> 
>>>>> I'd want to have chained exceptions still catchable by catch (Exception)
>>>>> because it would be a first to have the contents of the data influence
>>>>> its
>>>>> type. As far as the type system is concerned, catch (Exception) should
>>>>> catch
>>>>> Exceptions, whether or not they have a tail.
>>>>> 
>>>>> One possibility would be to move the Throwable to the front of the list.
>>>>> This also has its issues, for example the stack is unwound for a while
>>>>> and
>>>>> then not anymore (a Throwable is allowed to respect fewer rules than an
>>>>> Exception).
>>>>> 
>>>>> Ideas please?
>>>>> 
>>>>> 
>>>>> Andrei
>>>>> 
>>>>> On 1/11/11 1:57 AM, Don Clugston wrote:
>>>>>> 
>>>>>> I believe I have got TDPL exception chaining working correctly using
>>>>>> Windows Structured Exception Handling.
>>>>>> (This was far from easy!)
>>>>>> Central to making chaining work correctly, is that chaining must only
>>>>>> occur
>>>>>> when a collision occurs (not merely when two exceptions are in flight,
>>>>>> because one may be caught before it has any effect on the other). This
>>>>>> means that multiple chains of exceptions
>>>>>> may be in flight at any given time.
>>>>>> My code works in all nasty corner cases I've tested, including
>>>>>> multi-level collisions,
>>>>>> where two exceptions collide in a function, then collide again with an
>>>>>> even earlier exception chain in a finally block in a different
>>>>>> function.
>>>>>> 
>>>>>> So the general scheme appears to work.
>>>>>> But, there's something I'm unclear about. When should chained
>>>>>> exceptions be catchable?
>>>>>> They are very nasty creatures, and you really want to know when they
>>>>>> happen.
>>>>>> Presumably, an AssertError which occurs while processing an
>>>>>> FileException, should not be silently chained
>>>>>> and caught in the FileException.
>>>>>> In fact, should a chain containing an Error be catchable at all?
>>>>>> (If not, it still has to at least be catchable in the catchall handler
>>>>>> that wraps main()).
>>>>>> Many other schemes are possible, but I think it's important that the
>>>>>> rules remain simple.
>>>>>> 
>>>>>> One simple solution would be to make chained exceptions only catchable
>>>>>> by catch(Throwable).
>>>>>> _______________________________________________
>>>>>> phobos mailing list
>>>>>> phobos at puremagic.com
>>>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>>> 
>>>>> _______________________________________________
>>>>> phobos mailing list
>>>>> phobos at puremagic.com
>>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>>> 
>>>> _______________________________________________
>>>> phobos mailing list
>>>> phobos at puremagic.com
>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>> 
>>> _______________________________________________
>>> phobos mailing list
>>> phobos at puremagic.com
>>> http://lists.puremagic.com/mailman/listinfo/phobos
>> 
>> 
>> _______________________________________________
>> phobos mailing list
>> phobos at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/phobos
>> 
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
January 12, 2011
Two errors could still cause confusion though.

Sent from my iPhone

On Jan 12, 2011, at 12:55 AM, Don Clugston <dclugston at googlemail.com> wrote:

> On 12 January 2011 09:10, Don Clugston <dclugston at googlemail.com> wrote:
>> How about this rule:
>> ---
>> If all collateral exceptions are derived from Exception, the 'boss' or
>> Master Exception is the first exception thrown.
>> Otherwise, the first Error (or Throwable non-Exception) is the boss.
>> The exception, including all collateral exceptions, will be caught by
>> the first handler who can catch the boss.
>> ---
>> 
>> Two issues:
>> * If the boss is a collateral exception, we still need a way to find
>> out what the first exception was. Maybe need to add a 'first' (or
>> 'prev') member to Throwable?
> 
> Or, the chain could simply be:
> boss -> exception1 -> exception2 -> BypassThrowable -> exception3.
> 
> Where BypassThrowable is a class which acts as a placeholder for the boss.
> 
> This would be the simplest interim solution, since it doesn't require
> any code changes elsewhere, and would allow the
> existing error messages to continue to work correctly.
> 
> 
>> * It is still possible to throw an Object which isn't derived from
>> Throwable. Can we disallow this?
>> (We could throw a "NoThrowableError" if such an object is found to
>> have been thrown (can happen via casting)). This would remove some
>> really nasty corner cases.
>> 
>> 
>> On 12 January 2011 01:10, Andrei Alexandrescu <andrei at erdani.com> wrote:
>>> On 1/11/11 4:03 PM, Jonathan M Davis wrote:
>>>> 
>>>> On Tuesday, January 11, 2011 15:50:52 Andrei Alexandrescu wrote:
>>>>> 
>>>>> I don't think that's helpful. It complicates the flow a lot because now understanding how the program acts depends not on the types anymore, but on what happens dynamically. Makes it more difficult, not easier, to write robust code.
>>>>> 
>>>>> If I throw a FileException, I must catch a FileException with catch(FileException) regardless of what collateral exceptions have happened.
>>>> 
>>>> I agree as long as it's other Exceptions that have been thrown. But
>>>> Errors?
>>>> Aren't they typically supposed to kill your program?
>>>> 
>>>> - Jonathan M Davis
>>> 
>>> I agree that non-Exception Throwables are an out-of-band method of communication that deserves special attention.
>>> 
>>> Don, would it be difficult to make a non-Exception Throwable thrown during unwinding essentially come to the top of the foodchain and save everything in its tail?
>>> 
>>> 
>>> Andrei
>>> _______________________________________________
>>> phobos mailing list
>>> phobos at puremagic.com
>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>> 
>> 
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos