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 perls.

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"
}