Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

Deprecated use of $SIG{__DIE__} is useful

by clinton (Priest)
on Feb 28, 2009 at 17:32 UTC ( #747179=perlquestion: print w/replies, xml ) Need Help??

clinton has asked for the wisdom of the Perl Monks concerning the following question:

According to the perlvar docs for $SIG{__DIE__}:

Due to an implementation glitch, the $SIG{__DIE__} hook is called even inside an eval(). Do not use this to rewrite a pending exception in $@ , or as a bizarre substitute for overriding CORE::GLOBAL::die() . This strange action at a distance may be fixed in a future release so that $SIG{__DIE__} is only called if your program is about to exit, as was the original intent. Any other use is deprecated.

However, I find this particular behaviour useful. For instance, in my mod_perl application, pretty much all the code is wrapped in an eval which lets me return a nice error page to the user. Because of this glitch, I am able to inflate an uncaught exception into an error object, with attached stacktrace:

#=================================== sub uncaught_error { #=================================== die @_ if ref $_[0] # already an excep +tion object || ! defined $^S; # code is being co +mpiled my ($class) = caller(0); # throw() does the + work of inflating @_ = ( $class, 'Uncaught', join( '', @_ ) ); # an error message + into an exception object goto $class->can('throw') || \&throw; # of the relevant +class } $SIG{__DIE__} = \&uncaught_error;

Once this 'glitch' is fixed, the above code will no longer work (as in it will no longer give me a stack trace from the place where the error occurred) . Is there a better (not-about-to-be-deprecated) way to do this?



UPDATE: Added some comments to the code

Replies are listed 'Best First'.
Re: Deprecated use of $SIG{__DIE__} is useful (haste)
by tye (Sage) on Feb 28, 2009 at 19:01 UTC

    I read this about the same way I read much Perl documentation, written soon after somebody had a good idea and before much time was alotted for serious reflection on the idea. Like the prominent notice that was added to "use vars" saying that 'our' is better. Actually, there are good arguments for ways in which is better than 'our'.

    Or documentation that "use warnings" is better than -w. perllexwarn says "use warnings" is "more flexible" than "-w" and $^W. Actually, is just different. It can be used to do things that can't be done with -w/$^W but it also can't do many things that can be done with -w/$^W. And I find -w and $^W to be better suited for writing modules than "use warnings" (while "use warnings" is sometimes better when writing scripts).

    There could certainly be some improvements made to how $SIG{__DIE__} handlers nest with eval and other $SIG{__DIE__} handlers, but I would be quite surprised if p5p fulfilled that ancient threat and broke Devel::EvalError and lots of other reasonable uses.

    - tye        

Re: Deprecated use of $SIG{__DIE__} is useful
by ikegami (Patriarch) on Feb 28, 2009 at 19:03 UTC

    I'm not sure of the reason for the deprecation, but how is that different from the recommended

    BEGIN { *CORE::GLOBAL::die = sub { CORE::die @_ if ref $_[0] || ! defined $^S; my ($class) = caller(0); @_ = ( $class, 'Uncaught', join( '', @_ ) ); goto $class->can('throw') || \&throw; } }

      Overriding die catches calls to die('Error'), but it doesn't catch errors such as undefined values being thrown because I've used strict.

      In situations like this, where your code behaves in an unexpected way, it is useful to have a stack trace to see how we got to that point in the code, which I can only do with $SIG{__DIE__}.

        Indeed, thanks.

        Overriding die catches calls to die('Error'), but it doesn't catch errors such as undefined values being thrown because I've used strict.

        Neither does $SIG{__DIE__}. That would be $SIG{__WARN__}.

Re: Deprecated use of $SIG{__DIE__} is useful
by perrin (Chancellor) on Feb 28, 2009 at 23:04 UTC
    The alternative would be to have a top level eval{} around your program that catches all uncaught exceptions and can apply processing like this to them.

      No, a top-level eval cannot add a stack trace. It wouldn't catch the 'die' exception until after the stack had already been unrolled.

      - tye        

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://747179]
Approved by Corion
Front-paged by tye
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (3)
As of 2022-09-30 05:21 GMT
Find Nodes?
    Voting Booth?
    I prefer my indexes to start at:

    Results (125 votes). Check out past polls.