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

In Oracle PL/SQL and some other languages, it is possible to exit automatically from any part of a program during runtime as soon as an error occurs. Program execution then passes to something called an error handler.

It seems to me that Perl does not offer this feature. I wonder if there are ways to duplicate this functionality. How do Perl monks deal with runtime errors?

Replies are listed 'Best First'.
Re (tilly) 1: Are There Error Handlers in Perl?
by tilly (Archbishop) on Jan 20, 2001 at 05:21 UTC
    Everyone seems to want to talk about $SIG{__DIE__}. For much finer-grained control check out eval and $@. If you wish to combine the two mechanisms you will need to use $^S in your DIE handler. See perlvar. (Or use the perldoc command to read the local versions of these.)
Re: Are There Error Handlers in Perl?
by dws (Chancellor) on Jan 20, 2001 at 05:23 UTC
    To expand a bit on what cephas and tilly aluded to, here's an example:
    eval { foo(); }; print "caught '$@'\n" if $@; sub foo { # "throw" an error die "oops!"; }
Re: Are There Error Handlers in Perl?
by cephas (Pilgrim) on Jan 20, 2001 at 03:55 UTC
    You can actually set $SIG{__DIE__} with your handler, and it will be called before die does its deed. See perldoc -f die for more details....

    Also, if you just want to trap just certain exceptions, then you will probably want to use eval { expression } which will trap die and set $@ to appropriate message.

    If for some reason you want to use both of these in the same script, you'll want to be sure to read through the eval documentation to make sure you keep strangenesss to a minimum (would you really want to trap an error and have a SIG handler called and have die rethrown AGAIN???)

    cephas
(tye)Re: Are There Error Handlers in Perl?
by tye (Sage) on Jan 20, 2001 at 05:38 UTC

    To add to the unthreaded discussion :), I'd suggest you avoid $SIG{__DIE__} and use eval instead. $SIG{__DIE__} only works well if you are sure that you are the only one using it and you have to be careful about if other people use eval while you are using $SIG{__DIE__}.

    $SIG{__WARN__} made sense and generalizing it to also have a $SIG{__DIE__} was a bad idea.

            - tye (but my friends call me "Tye")
Re: Are There Error Handlers in Perl?
by stephen (Priest) on Jan 20, 2001 at 05:09 UTC
    You'll find documentation at perlman:perlvar; search for '%SIG'. Here's some example code.
    # Handles when we exit with a 'die "foo"...' sub die_handler { my ($msg) = @_; shutdown_now("Died; $msg"); } $SIG{__DIE__} = \&die_handler;
    You can also install signal handlers on POSIX-compliant systems using sigaction(); see POSIX for details.

    stephen

Re: Are There Error Handlers in Perl?
by repson (Chaplain) on Jan 20, 2001 at 09:34 UTC
    People are saying that $SIG{__DIE__} is a bad thing. This is true if die is just used with strings.

    However this document at perl.apache.org, despite being written for mod_perl, gives good instructions for the procedure of dieing with objects. This allows you to do this sort of thing:

    die My::Exception->SomeException( foo => "bar" );

    And then deal with the data SomeException and (foo => 'bar') in the exception class My::Exception.

    Or you can overload the die function, allowing other trickery.

      This is exactly the type of things that I think you should do with eval {}. If you are going to be throwing exceptions then you need to be able to nest your exception catchers. This is exactly how eval {} works.

      No matter how tricky you get with saving and queueing $SIG{__DIE__} handlers, you'll never get a $SIG{__DIE__} handler to unwind part of the stack so the third handler up can deal with an exception that the inner two handlers couldn't continue past.

      And all you need is one person somewhere setting $SIG{__DIE__} without following your queueing method and you lose.

      I get the feeling that $SIG{__DIE__} is much more popular than eval {}. I'm not sure if this is due to wording in the documentation or an overblown fear of "slow eval".

              - tye (and I'll see an end to $SIG{__DIE__} and File::FindBin yet!)
        I suspect overblown fears. Folks, read eval and pay close attention to the fact that when you eval a block it is resolved at compile time and it is fast. In fact it should be be both faster and more reliable than throwing and rethrowing signal handlers. (As well as a heck of a lot simpler.)

        Oh, you might also pay attention to the suggested use of local $SIG{__DIE__} handlers within an eval as a work around when other people get it wrong. That is slower, but working around other people's mistakes generally is.