How to properly use the try catch in perl that error.pm provides?
You're probably better off using Try::Tiny which will help you avoid a number of pitfalls with older perl
s.
use Try::Tiny;
try {
die "foo";
} catch {
warn "caught error: $_";
};
If you want something a bit more powerful than Try::Tiny, you might want to try looking at the TryCatch module in CPAN.
Last I checked, Error was deprecated. But here's how you would do it without that module:
eval {
die "Oops!";
1;
} or do {
my $e = $@;
print("Something went wrong: $e\n");
};
Basically, use eval instead of try
, die instead of throw
, and look for the exception in $@
. The true value at the end of the eval block is part of an idiom to prevent $@
from unintentionally changing before it is used again in Perl versions older than 5.14, see P::C::P::ErrorHandling::RequireCheckingReturnValueOfEval for details. For example, this code suffers from this flaw.
# BAD, DO NOT USE WITH PERLS OLDER THAN 5.14
eval {
die "Oops!";
};
if (my $e = $@) {
print("Something went wrong: $e\n");
}
# BAD, DO NOT USE WITH PERLS OLDER THAN 5.14
But note that many Perl operations do not raise exceptions when they fail; they simply return an error code. This behavior can be altered via autodie for builtins and standard modules. If you're using autodie
, then the standard way of doing try/catch is this (straight out of the autodie perldoc):
use feature qw(switch);
eval {
use autodie;
open(my $fh, '<', $some_file);
my @records = <$fh>;
# Do things with @records...
close($fh);
};
given ($@) {
when (undef) { say "No error"; }
when ('open') { say "Error from open"; }
when (':io') { say "Non-open, IO error."; }
when (':all') { say "All other autodie errors." }
default { say "Not an autodie error at all." }
}
For getting a stacktrace, look at Carp.
Native try
/catch
/finally
.
Perl now has native support for try
/catch
/finally
. You can use it like this. As of Perl v5.36, It's currently experimental.
use experimental "try";
try { die 42 }
catch ($err) {
print "got $err"
}