[dmd-internals] Throwing Errors

Don Clugston dclugston at googlemail.com
Mon Mar 12 14:34:25 PDT 2012


On 12 March 2012 22:06, Jonathan M Davis <jmdavisProg at gmx.com> wrote:
> On Monday, March 12, 2012 21:29:25 Don Clugston wrote:
>> I went to a lot of trouble to ensure the exception chaining behaviour
>> of Errors vs Exceptions.
>>
>> Personally, I just don't buy the argument that the entire system is in
>> an invalid state when an Error occurs. It's a sign that some subsystem
>> is in a invalid state, but how much of the whole app is invalid,
>> depends on the particular situation. For example, if you're
>> extensively using class invariants and contracts, and you get an
>> AssertError, then the possible damage is pretty small. Especially if
>> it is an assert failure in a pure @safe function; cleanup will be
>> perfectly safe in that situation.
>>
>> I would have thought that if you had a truly fatal error, you would
>> have called exit() or something, instead of throwing an Error.
>
> When an Error is thrown, the program is in a potentially invalid state. How
> invalid it is, depends on the Error. And the fact that cleanup isn't
> guaranteed _definitely_ puts the program in an invalid state when an Error is
> thrown unless it's caught very close to its throw point.
>
> I'm not sure how much it matters whether there is any attempt to cleanup from
> Errors except that if the Error _does_ indicate something which would
> invalidate the cleanup code, it could cause serious problems. The main one
> that I can think of is OutOfMemoryError, since if any cleanup code then tries
> to allocate anything, it's going to fail. Of course, that would then result in
> _another_ OutOfMemoryError, so it may be that that pretty much takes care of
> itself and really isn't a big deal.
>
> Certainly, in the general case, even if cleanup _is_ guaranteed, catching
> Errors is a bad idea because of the types of problems that they generally
> indicate. But there _are_ cases where catching Errors can be useful - the most
> prevalent one being catching AssertErrors in unit tests. Anyone trying to use
> a fancier unit testing framework (which I don't personally see any need for,
> but some people are _very_ interested in it - e.g. Jacob Carlborg) is going to
> have to do that. And in rare cases, even catching OutOfMemoryError makes some
> sense. You just have to know what you're doing and be careful.
>
> The _biggest_ thing with Errors is simply that they're not Exceptions, so
>
> catch(Exception e) {}
>
> won't catch them, and nothrow isn't affected by them. That right there provides
> their primary benefit. Personally, I'm on the fence as to whether attempting
> cleanup when an Error is thrown is a good idea or not. Certainly, in the unit
> testing case, it would certainly be desirable. Most of the rest, it probably
> doesn't matter all that much, but it would arguably be desirable to skip
> cleanup for them so that the amount of weird stuff that can happen on shutting
> down the program can be minimized. But of course, it also makes it harder to
> guarantee that certain things are done on shutdown, and it's not all that
> uncommon to have stuff that you want to _guarantee_ runs on shutdown, even if
> it's not a clean shutdown (or even _especially_ if it's not a clean shutdown).
>
> The other thing to consider is the fact that very few people seem to
> understand that Errors in flight aren't guaranteed to execute scope statements,
> destructors, or finally blocks.

Well  I've never heard that before, and I wrote the code on Windows to
make sure that they do get executed.
It's not an accident that it works.


More information about the dmd-internals mailing list