[dmd-internals] Throwing Errors

Sean Kelly sean at invisibleduck.org
Thu Mar 15 16:48:01 PDT 2012


On Mar 15, 2012, at 3:25 PM, Walter Bright wrote:
> 
> On 3/15/2012 2:39 PM, Jonathan M Davis wrote:
>> On Thursday, March 15, 2012 14:22:49 Walter Bright wrote:
>>> On 3/15/2012 9:29 AM, Sean Kelly wrote:
>>>> Is the program really corrupted though?
>>> You cannot know that.
>>> 
>>> I really think that going down the path of thinking one can recover from
>>> programming bugs is the route to disaster. It goes against everything I know
>>> about how to make safe, reliable systems.
>> There's a difference between saying that Errors are not recoverable and making
>> it so that cleanup code runs when Errors are thrown. Catching an Error and
>> continuing the execution of your program is almost never a good idea, but
>> catching it, doing some cleanup and rethrowing it (as finally, scope(failure),
>> and scope(exit) would do) is a different matter. No, it may not work, but it
>> can also allow you to do things that need to be done at cleanup. And _not_
>> running scope statements, destructors, and finally blocks makes catching Errors
>> even _less_ safe even when it _does_ make sense. And upon occasion, catching
>> Errors _does_ make sense even for cases other than cleanup.
> 
> I don't agree. The more code you run after a program bug, the more likely you aren't going to be able to run your shutdown/logging code.
> 
> If any of that cleanup code actually needs to run on program bug shutdown, it still can be done with catch/throw. The other stuff assumes normal operation and is not needed to be run for shutdown/logging.

So I'm guessing that scope(failure) clauses will be executed when an Error is thrown because that's the point in having them.  But I imagine scope(exit) clauses will be run for Exceptions but not for Errors, despite the fact that the scope is clearly exiting via stack unwinding?  What's the difference in saying "I want this code to run when scope exits via a throw" vs. "I always want this to run regardless of how scope exits?"  I see the addition of special cases causing confusion here.

What if we kept the existing throw behavior and added a runtime callback, similar to onAssertError, that is called whenever any Error is about to be thrown?  At this point the user has the option interrupting the usual stack unwinding logic in favor of something more stringent, say logging an error and immediately calling abort()? This would allow those who don't want to take any chances with code being run between the throw point and their shutdown to do so, while leaving a consistent execution model for the average user?  Or flip the situation and make immediate abort the default behavior but let the user override to throw instead?  If the Error instance is passed to the callback the behavior could even vary based on the actual type of the Error generated.


More information about the dmd-internals mailing list