Sponsoring The Perl Toolchain Summit 2025: Help make this important event another success Learn more

NAME
Feature::Compat::Try - make try/catch syntax available
SYNOPSIS
use Feature::Compat::Try;
sub foo
{
try {
attempt_a_thing();
return "success";
}
catch ($e) {
warn "It failed - $e";
return "failure";
}
}
DESCRIPTION
This module makes syntax support for try/catch control flow easily
available.
Perl added such syntax at version 5.34.0, and extended it to support
optional finally blocks at 5.35.9, which is enabled by
use feature 'try';
On that version of perl or later, this module simply enables the core
feature equivalent to using it directly. On such perls, this module
will install with no non-core dependencies, and requires no C compiler.
On older versions of perl before such syntax is available, it is
currently provided instead using the Syntax::Keyword::Try module,
imported with a special set of options to configure it to recognise
exactly and only the same syntax as the core perl feature, thus
ensuring that any code using it will still continue to function on that
newer perl.
KEYWORDS
try
try {
STATEMENTS...
}
...
A try statement provides the main body of code that will be invoked,
and must be followed by a catch statement. It may optionally be
followed by a finally statement.
Execution of the try statement itself begins from the block given to
the statement and continues until either it throws an exception, or
completes successfully by reaching the end of the block.
The body of a try {} block may contain a return expression. If
executed, such an expression will cause the entire containing function
to return with the value provided. This is different from a plain eval
{} block, in which circumstance only the eval itself would return, not
the entire function.
The body of a try {} block may contain loop control expressions (redo,
next, last) which will have their usual effect on any loops that the
try {} block is contained by.
The parsing rules for the set of statements (the try block and its
associated catch) are such that they are parsed as a self-contained
statement. Because of this, there is no need to end with a terminating
semicolon.
Even though it parses as a statement and not an expression, a try block
can still yield a value if it appears as the final statement in its
containing sub or do block. For example:
my $result = do {
try { attempt_func() }
catch ($e) { "Fallback Value" }
};
catch
...
catch ($var) {
STATEMENTS...
}
A catch statement provides a block of code to the preceding try
statement that will be invoked in the case that the main block of code
throws an exception. A new lexical variable is created to store the
exception in.
Presence of this catch statement causes any exception thrown by the
preceding try block to be non-fatal to the surrounding code. If the
catch block wishes to optionally handle some exceptions but not others,
it can re-raise it (or another exception) by calling die in the usual
manner.
As with try, the body of a catch {} block may also contain a return
expression, which as before, has its usual meaning, causing the entire
containing function to return with the given value. The body may also
contain loop control expressions (redo, next or last) which also have
their usual effect.
finally
...
finally {
STATEMENTS...
}
A finally statement provides an optional block of code to the preceding
try/catch pair which is executed afterwards, both in the case of a
normal execution or a thrown exception. This code block may be used to
provide whatever clean-up operations might be required by preceding
code.
Because it is executed during a stack cleanup operation, a finally {}
block may not cause the containing function to return, or to alter the
return value of it. It also cannot see the containing function's @_
arguments array (though as it is block scoped within the function, it
will continue to share any normal lexical variables declared up until
that point). It is protected from disturbing the value of $@. If the
finally {} block code throws an exception, this will be printed as a
warning and discarded, leaving $@ containing the original exception, if
one existed. =head1 COMPATIBILITY NOTES
This module may use either Syntax::Keyword::Try or the perl core try
feature to implement its syntax. While the two behave very similarly,
and both conform to the description given above, the following
differences should be noted.
* Visibility to caller()
The Syntax::Keyword::Try module implements try blocks by using eval
frames. As a result, they are visible to the caller() function and
hence to things like Carp::longmess when viewed as stack traces.
By comparison, core's feature 'try' creates a new kind of context
stack entry that is ignored by caller() and hence these blocks do not
show up in stack traces.
This should not matter to most use-cases - e.g. even Carp::croak will
be fine here. But if you are using caller() with calculated indexes
to inspect the state of callers to your code and there may be try
frames in the way, you will need to somehow account for the
difference in stack height.
* B::Deparse
The core feature 'try' is implemented by emitting real opcodes that
represent its behaviour, which is recognised by the version of
B::Deparse that ships with core perl. As a result, any code using
this implementation will deparse currently with tools like perl
-MO=Deparse ..., or others related to it such as coverage checkers.
By comparison, since Syntax::Keyword::Try uses OP_CUSTOM it is not
recognised by B::Deparse and so attempts to deparse this will result
in error messages like
unexpected OP_CUSTOM (catch) at ...
This is rather unavoidable due to the way that B::Deparse is
implemented and does not easily support custom operators.
AUTHOR
Paul Evans <leonerd@leonerd.org.uk>