Reputation: 2983
I have found that there is the module Error that provides try and catch functionality like in java. But I am confused at how you can print the exception that returns.
I would like to understand how to do the following
try {
// do something that will fail!
} catch (Error e) {
// Print out the exception that occurred
System.out.println(e.getMessage());
}
How do I get the print of the error with the stack trace?
Upvotes: 45
Views: 101327
Reputation: 1
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"
}
Upvotes: 5
Reputation: 159
As has been said, the old Error module is deprecated, but it has continued to work for me long after. It's been a while since I last checked if its still working. I tried some of the "better" replacements and found them all lacking, so I still use Error.
Here's a sample from some code that's pretty straight forward and prints the error that was caught. This is from an app I wrote that uses Storable to store and retrieve serialized perl objects to an MLDBM backend file.
use Error(':try');
...
try {
$obj = retrieve( $objfile );
} catch Error::Simple with {
my $E = shift;
warn "Caught error $E";
};
This returns a message something like:
Caught error Not a HASH reference at ./json2text.pl line 12.
If you want the full stack trace, you can either run the code under the debugger, or you can read about the stacktrace method on the perldoc for the Error class itself. I never found it necessary to have apps not running under the debugger to print full stack traces, so I don't have any examples of that in my collection to paste a sample from.
I hope this helps. Sometimes you just have to wait for a dinosaur to show up.
Upvotes: 0
Reputation: 79
IMHO Syntax::Keyword::Try
is a better option than Try::Tiny
for most cases.
Try::Tiny
is an order of magnitude slower than either eval or Syntax::Keyword::Try
. It depends on your application if this is a problem or not. For many applications its not important.
Also if you are a visitor from another language, Try::Tiny
has syntax quirks which make it not quite the try/catch you are used to.
Upvotes: 2
Reputation: 1073
Unfortunately TryCatch has been broken with the new version 0.006020 of Devel::Declare and there seems to be no intention of fixing it. The perl core developers team also complained about the funky stuff TryCatch was relying on to make it work.
Instead there is a new implementation called Nice::Try, which is a perfect replacement.
There is no need to have semi colon on the last brace like Try::Tiny.
You can also do exception variable assignment like
try
{
# something
}
catch( $e )
{
# catch this in $e
}
It also works using class exception like
try
{
# something
}
catch( Exception $e )
{
# catch this in $e
}
And it also supports finally
. Its features set make it quite unique.
Full disclosure: I have developed this module when TryCatch got broken.
Upvotes: 1
Reputation: 81
If you want something a bit more powerful than Try::Tiny, you might want to try looking at the TryCatch module in CPAN.
Upvotes: 8
Reputation: 118128
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: $_";
};
Upvotes: 63
Reputation: 95242
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.
Upvotes: 58