Exception/Error division in D

Sean Kelly sean at invisibleduck.org
Wed May 30 08:17:03 PDT 2012


On May 30, 2012, at 8:05 AM, "Steven Schveighoffer" <schveiguy at yahoo.com> wrote:

> On Wed, 30 May 2012 05:32:00 -0400, Don Clugston <dac at nospam.com> wrote:
> 
>> On 30/05/12 10:40, Jonathan M Davis wrote:
>>> On Wednesday, May 30, 2012 10:26:36 deadalnix wrote:
>>>> The fact that error don't trigger scope and everything is nonsensial.
>>> 
>>> If an Error is truly unrecoverable (as they're generally supposed to be), then
>>> what does it matter? Something fatal occured in your program, so it
>>> terminates. Because it's an Error, you can get a stack trace and report
>>> something before the program actually terminates, but continuing execution
>>> after an Error is considered to be truly _bad_ idea, so in general, why does
>>> it matter whether scope statements, finally blocks, or destructors get
>>> executed? It's only rarer cases where you're trying to do something like
>>> create a unit test framework on top of assert that you would need to catch an
>>> Error, and that's questionable enough as it is. In normal program execution,
>>> an error is fatal, so cleanup is irrelevant and even potentially dangerous,
>>> because your program is already in an invalid state.
>> 
>> That's true for things like segfaults, but in the case of an AssertError, there's no reason to believe that cleanup would cause any damage.
> 
> There's also no reason to assume that orderly cleanup *doesn't* cause any damage.  In fact, it's not reasonable to assume *anything*.
> 
> Which is the point.  If you want to recover from an error, you have to do it manually.  It should be doable, but the default handling should not need to be defined (i.e. implementations should be free to do whatever they want).
> 
> But there is no reasonable *default* for handling an error that the runtime can assume.
> 
> I'd classify errors/exceptions into three categories:
> 
> 1. corruption/segfault -- not recoverable under any reasonable circumstances.  Special cases exist (such as a custom paging mechanism).
> 2. program invariant errors (i.e. assert errors) --  Recovery is not defined by the runtime, so you must do it manually.  Any decision the runtime makes will be arbitrary, and could be wrong.
> 3. try/catch exceptions -- these are planned for and *expected* to occur because the program cannot control it's environment.  e.g. EOF when none was expected.
> 
> The largest problem with the difference between 2 and 3 is the actual decision of whether an exceptional case is categorized as 2 or 3 can be decoupled from the code that decides between them.
> 
> For example:
> 
> double invert(double x)
> {
>   assertOrEnfoce?(x != 0); // which should it be?
>   return 1.0/x;
> }
> 
> case 1:
> 
> void main()
> {
>    writeln(invert(0)); // clearly a program error
> }
> 
> case 2:
> 
> int main(string[] args)
> {
>   writeln(invert(to!double(args[1])); // clearly a catchable error
> }
> 
> I don't know of a good way to solve that...

Sounds like a good argument for the assert handler in core.runtime. 


More information about the Digitalmars-d mailing list