http://qs321.pair.com?node_id=427160

I've stumbled on a use of die that can't be caught with an eval.

In most normal uses,

eval { something_that_might_die(); }; print "Caught: $@" if $@;
will let you simulate an exception being thrown and caught. If somewhere inside of something_that_might_die() there's a
die "exception!\n";
the string will end up in $@. This almost always works.

The case where this throw/catch mechanism doesn't work is inside a destructor. The code

package Thing; sub new { bless {}, shift } sub DESTROY { my ($self) = @_; print "$self is dying\n"; die "$self died\n"; } package main; eval { my $b = Thing->new(); undef $b; }; print "Caught: $@\n" if $@;
prints
Thing=HASH(0x811b24c) is dying
and the die disappears (on Perl 5.6 and 5.8). To further confound matters, if you create and destroy the object outside of an eval (e.g., if you comment out two lines in the fragment above), you'll see
Thing=HASH(0x811b24c) is dying! Caught: (in cleanup) Thing=HASH(0x811b24c) died
so the die is being caught, but just not in a place that you can necessarily get at and catch yourself.

This doesn't surprise me. Object destruction is an interesting edge case, and it makes a certain amount of sense to ignore errors. Still, if you're depending on wrapping a bunch of code in an eval to trap exceptions, and some of that code is doing cleanup in constructors that might fail, the lost exception might come as a rude surprise.

Update: More experiments. This is looking like a pre 5.8 vs post 5.8 thing.

Perldie catchable
A 5.6 I'll have to find again no
v5.8.0 built for MSWin32-x86-multi-thread yes
v5.8.0 built for i386-linux-thread-multi yes
v5.8.3 built for i386-freebsd yes
v5.8.5 built for i386-linux-thread-multi yes

Replies are listed 'Best First'.
Re: An uncatchable die
by lestrrat (Deacon) on Feb 02, 2005 at 10:06 UTC

    I encountered something similar with destructors a while back. My case was that the eval{} block in my destructor was actually writing over the previous error status, and therefore making it looks as though there *was* no error.

    DESTROY and eval definitely don't play nice in some edge cases. Module authors ought to be careful not to introduce code like this (reminder to self)

Re: An uncatchable die
by redlemon (Hermit) on Feb 02, 2005 at 15:01 UTC

    hmmm, my perl 5.8.5 on linux gives:

    Thing=HASH(0x8142384) is dying (in cleanup) Thing=HASH(0x8142384) died Caught: (in cleanup) Thing=HASH(0x8142384) died

    Which gives another problem, getting rid of the first message.