How do you safely call a function that might raise an exception? How do you create a function that raises an exception?
Sometimes you encounter a problem so exceptional that merely returning an error isn't strong enough, because the caller could ignore the error. Use
die
STRING
from your function to trigger an exception:
die "some message"; # raise exception
The caller can wrap the function call in an
eval
to intercept that exception, and then consult the special variable
$@
to see what happened:
eval { func() }; if ($@) { warn "func raised an exception: $@"; }
Raising exceptions is not a facility to be used lightly. Most functions should return an error using a bare
return
statement. Wrapping every call in a trap is tedious and unsightly, removing the appeal of using exceptions in the first place.
But on rare occasion, failure in a function should cause the entire program to abort. Rather than calling the irrecoverable
exit
function, you should call
die
instead, which at least gives the programmer the chance to cope. If no exception handler has been installed via
eval
, then the program aborts at that point.
To detect such a failure program, wrap the call to the function with a block
eval
. The
$@
variable will be set to the offending exception if one occurred; otherwise, it will be false.
eval { $val = func() }; warn "func blew up: $@" if $@;
Any
eval
catches all exceptions, not just specific ones. Usually you should propagate unexpected exceptions to an enclosing hander. For example, suppose your function raised an exception containing the string
"Full
moon!"
. You could safely trap that exception while letting the others through by inspecting the
$@
variable. Calling
die
without an argument uses the contents of
$@
and the current context to construct a new exception string.
eval { $val = func() }; if ($@ && $@ !~ /Full moon!/) { die; # re-raise unknown errors }
If the function is part of a module, consider using the Carp module and call
croak
or
confess
instead of
die
. The only difference between
die
and
croak
is that with
croak
, the error appears to be from the caller's perspective, not the module's. The
confess
function, on the other hand, creates a full stack backtrace of who called whom and with what arguments.
Another intriguing possibility is for the function to detect that its return value is being completely ignored; that is, it is being called in a void context. In that case, returning an error indication would be useless, so raise an exception instead.
Of course, just because it's not voided doesn't mean the return value is being dealt with appropriately. But if it is voided, it's certainly not being checked.
if (defined wantarray()) { return; } else { die "pay attention to my error!"; }
The
$@
variable in
Chapter 2
of
Programming Perl
and
perlvar
(1); the
die
and
eval
functions in
Chapter 3
of
Programming Perl
and
perlfunc
(1);
Recipe 10.15
;
Recipe 12.2
;
Recipe 16.21
Copyright © 2001 O'Reilly & Associates. All rights reserved.