[dmd-internals] Throwing Errors

Jonathan M Davis jmdavisProg at gmx.com
Thu Mar 15 14:39:04 PDT 2012


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.

There is a difference between recovering from an Error and a recovering from a 
programming bug. Not all Errors necessarily indicate that there's a bug in the 
program. They just indicate that they've hit what is almost certainly a fatal 
condition. For instance, OutOfMemoryError is generally fatal, but it doesn't 
necessarily indicate a bug in the program. If caught close to the throw point, 
it might be possible to recover in some cases. It's just that the current 
state _is_ fatal unless you can do something to fix it. In most cases you 
can't, but in a few, rare ones, you can.

Catching an AssertError in normal code is a hugely bad idea - they _do_ 
indicate program bugs - but it could still make sense in unit testing code - 
especially if you're trying to build a fancier unit testing framework on top 
of the built-in one (to improve output or whatever).

So no, trying to recover from programming bugs is a _not_ a good idea, but 
there _are_ rare cases where catching Errors makes sense, and making it so 
that they skip scope statements, destructors, and finally blocks makes them 
even _less_ safe to catch and makes it so that you often can't recover from an 
Error even in the rare cases where you should be able to.

The main question that I see is whether trying to run cleanup code when an 
Error is thrown is likely to make things worse or not. If that's a really high 
risk, then it may be better to have scope statements, finally blocks, and 
destructors skipped. But if it's at all debatable as to whether it's better or 
worse to run cleanup code when an Error is thrown, then I'd argue that code 
will be _less_ buggy if they're run when an Error is thrown. That doesn't make 
it so that the programmer should be catching Errors much, but it _does_ make 
it so that it's reasonably safe in the few cases where it _does_ make sense to 
catch them.

- Jonathan M Davis


More information about the dmd-internals mailing list