views:

172

answers:

5

I'm learning Perl, and in a lot of the examples I see errors are handled like this

open FILE, "file.txt" or die $!;

Is die in the middle of a script really the best way to deal with an error?

+3  A: 

The more modern approach is to use the Carp standard library.

use Carp;
my $fh;
open $fh, '<', "file.txt" or confess($!);

The main advantage is it gives a stack trace on death.

Paul Nathan
Well, croak doesn't give a stack trace unless you set some other Carp things.
brian d foy
@brian: whoop, fixed.
Paul Nathan
Thanks! I did not know about Carps.... but since when do Carps croak?
Francisco Garcia
Carps typically don't confess, either. However, there *is* a fish called a croaker on the east coast of the USA. But, they aren't carp.
Paul Nathan
@Paul Nathan, since this is Perl that sort of makes perfect sense. ;)
Tuzo
A: 

I use die but I wrap it in eval blocks for control over the error handling:

my $status = eval
{
    # Some code...
};

If the 'eval' fails:

  1. $status will be undefined.
  2. $@ will be set to whatever error message was produced (or the contents of a die)

If the 'eval' succeeds:

  1. $status will be the last returned value of the block.
  2. $@ will be set to ''.
Nick Gotch
There are a ton of problems with `eval {}` that need obscure work-arounds. Use Try::Tiny instead. It wraps up all the noxious boilerplate in a clean, easy to use package.
daotoad
There are a ton of problems with `eval {}` that need obscure work-arounds... if you care about identifying the error. If you're going to take the same action regardless of its cause, a simple block `eval` works fine. But, yeah: Use `Try::Tiny` in all other cases.
Dave Sherohman
I'll try that out next time I write some Perl. I use this way to fake a try-catch (by adding a check of $@ after the eval block.) Thanks for the tips.
Nick Gotch
+15  A: 

Whether die is appropriate in the middle of the script really depends on what you're doing. If it's a small tool with a couple hundred lines, then it's probably fine. If it's a large object-oriented system with lots of classes and interconnected code, then maybe an exception object would be better.

For handling exceptions from Perl builtins, I like to use autodie. It catches failures from open and other system calls and will throw exceptions for you, without having to do the or die bit. These exceptions can be caught with a eval { }, or better yet, by using Try::Tiny.

friedo
+1 for suggesting `autodie`.
Evan Carroll
I've always thought they should call it `autoOrDie` :)
friedo
+8  A: 

Since I use Log::Log4perl almost everywhere, I use $logger->logdie instead of die. And if you want to have more control over your exceptions, consider Exception::Class.

It is better to catch your exceptions with Try::Tiny (see its documentation why).

codeholic
+6  A: 
Axeman