tags:

views:

258

answers:

1

I've got a bunch of questions about how people use exceptions in Perl. I've included some background notes on exceptions, skip this if you want, but please take a moment to read the questions and respond to them.

Thanks.

Background on Perl Exceptions

Perl has a very basic built-in exception system that provides a spring-board for more sophisticated usage.

For example die "I ate a bug.\n"; throws an exception with a string assigned to $@.

You can also throw an object, instead of a string: die BadBug->new('I ate a bug.');

You can even install a signal handler to catch the SIGDIE psuedo-signal. Here's a handler that rethrows exceptions as objects if they aren't already.

$SIG{__DIE__} = sub { 
    my $e = shift; 
    $e = ExceptionObject->new( $e ) unless blessed $e;
    die $e;
}

This pattern is used in a number of CPAN modules. but perlvar says:

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.

So now I wonder if objectifying exceptions in sigdie is evil.

The Questions

  1. Do you use exception objects? If so, which one and why? If not, why not?

  2. If you don't use exception objects, what would entice you to use them?

  3. If you do use exception objects, what do you hate about them, and what could be better?

  4. Is objectifying exceptions in the DIE handler a bad idea?

  5. Where should I objectify my exceptions? In my eval{} wrapper? In a sigdie handler?

  6. Are there any papers, articles or other resources on exceptions in general and in Perl that you find useful or enlightening.

Cross-posted at Perlmonks.

+3  A: 

I don't use exception objects very often; mostly because a string is usually enough and involves less work. This is because there is usually nothing the program can do about the exception. If it could have avoided the exception, it wouldn't have caused it in the first place.

If you can do something about the exceptions, use objects. If you are just going to kill the program (or some subset, say, a web request), save yourself the effort of coming up with an elaborate hierarchy of objects that do nothing more than contain a message.

As for number 4; $SIG{__DIE__} should never be used. It doesn't compose; if one module expects sigdie to work in one way, and another module is loaded that makes it work some other way, those modules can't be used in the same program anymore. So don't do that.

If you want to use objects, just do the very-boring die Object->new( ... ). It may not be exciting as some super-awesome magic somewhere, but it always works and the code does exactly what it says.

jrockway