How to properly use the try catch in perl that err

2019-03-17 13:36发布

问题:

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?

回答1:

You're probably better off using Try::Tiny which will help you avoid a number of pitfalls with older perls.

use Try::Tiny;

try {
        die "foo";
} catch {
        warn "caught error: $_";
};


回答2:

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.



回答3:

If you want something a bit more powerful than Try::Tiny, you might want to try looking at the TryCatch module in CPAN.