Trapping Errors with eval
Perl provides a simple way to catch fatal errors—wrap the code in an eval block:
eval { $barney = $fred / $dino } ; # divide-by-zero error?
Now, even if $dino is zero, that line won’t crash the program. The eval is actually an expression (not a control structure, like while or foreach), so that semicolon is required at the end of the block. When a normally fatal error happens during the execution of an eval block, the block is done running, but the program doesn’t crash. So that means that right after an eval finishes, you’ll want to know whether it exited normally or whether it caught a fatal error for you. The answer is in the special $@ variable. If the eval caught a fatal error, $@ will hold what would have been the program’s dying words, perhaps something like: Illegal division by zero at my_program line 12. If there was no error, $@ will be empty. Of course, that means that $@ is a useful Boolean (true/false) value (true if there was an error), so you’ll sometimes see code like this after an eval block:
print "An error occurred: $@" if $@;
foreach my $person (qw/ fred wilma betty barney dino pebbles /) {
or die "Can't open file '$person': $!";
my $average = $total/$count;
print "Average for file $person was $average\n";
&do_something($person, $average);
print "An error occurred ($@), continuing\n";
There are four kinds of problems that eval can’t trap. The first group are the very serious errors that crash Perl itself, such as running out of memory or getting an untrapped signal. Since Perl itself isn’t running, there’s no way it can trap these errors.* Of course, syntax errors inside the eval block are caught at compile time—they’re never returned in $@.
The exit operator terminates the program at once, even if it’s called from a subroutine inside an eval block. (This correctly implies that when writing a subroutine, you should use die rather than exit to signal when something goes wrong.)
The fourth and final kind of problem that an eval block can’t trap are warnings, either user-generated ones (from warn) or Perl’s internally generated warnings (requested with the -w command-line option or the use warnings pragma). There’s a separate mechanism from eval for trapping warnings; see the discussion of the__WARN__ pseudosignal in the Perl documentation for the details.