--- name: catch signature: 'catch (VAR) BLOCK' since: 5.34 status: documented categories: ["Control flow"] --- ```{index} single: catch; Perl built-in ``` *[Control flow](../perlfunc-by-category)* # catch Handle an exception thrown by a preceding [`try`](try) block. `catch` is the second half of the [`try`](try)/`catch` construct. It is not a standalone statement: it follows a [`try`](try) block, declares a lexical `VAR` to receive the exception value, and runs its `BLOCK` only when the [`try`](try) block died. If the [`try`](try) block completed normally the `catch` block is skipped. Control then resumes at the statement following the whole construct (or the [`finally`](finally) block, if one is present). This syntax must be enabled with `use feature 'try'`. [`try`](try) and `catch` are non-experimental as of Perl 5.40. ## Synopsis ```perl try BLOCK catch (VAR) BLOCK try BLOCK catch (VAR) BLOCK finally BLOCK ``` ## What you get back `catch` is not a function call and has no return in the expression sense. Like other control-flow constructs, the value of the whole [`try`](try)/`catch` is the value of whichever block ran last — useful inside a [`do`](do) block or as the tail expression of a subroutine: ```perl my $value = do { try { fetch_thing(@args); } catch ($e) { warn "fetch failed: $e"; $DEFAULT; } }; ``` If [`try`](try) ran to completion, the construct yields the [`try`](try) block's last value and `VAR` is never bound. If [`try`](try) died, the construct yields the `catch` block's last value. ## The VAR declaration The parentheses after `catch` are mandatory and must contain exactly one scalar variable declaration. It behaves like a [`my`](my) declaration — the `my` keyword is implicit, as in subroutine signatures: ```perl catch ($e) { ... } # $e is a new lexical catch (my $e) { ... } # syntax error — 'my' is already implied ``` `VAR` is scoped to the `catch` block only. It is not visible in the preceding [`try`](try) block, in any following [`finally`](finally) block, or after the construct. Its value is whatever the [`try`](try) block threw — a string, a list that stringified into one, or a reference, typically a blessed exception object. See [`die`](die) for how the exception value is produced. Unlike [`eval`](eval), `catch` does **not** read or clear [`$@`](../perlvar); the exception travels through `VAR` directly. [`$@`](../perlvar) is untouched by the construct. ## Global state it touches `catch` itself touches no special variables. The [`try`](try)/`catch` construct as a whole leaves [`$@`](../perlvar) unchanged — a deliberate divergence from [`eval`](eval) intended to stop callers from conflating the two idioms. If you need [`$@`](../perlvar)-style inspection, use [`eval`](eval) instead. ## Examples Catch a simple string exception and report it: ```perl use feature 'try'; try { risky(); } catch ($e) { warn "risky failed: $e"; } ``` Inspect a structured exception object: ```perl try { process($record); } catch ($e) { if (ref($e) && $e->isa('My::NotFound')) { return; # missing is fine } die $e; # re-throw everything else } ``` Re-throw unchanged with [`die`](die). Because `catch` does not touch [`$@`](../perlvar), you re-throw the variable you bound, not [`$@`](../perlvar): ```perl try { step(); } catch ($e) { log_error($e); die $e; # propagates to the next handler } ``` Produce a value from the construct without [`return`](return). Using [`return`](return) inside [`try`](try) or `catch` returns from the **enclosing subroutine**, not from the construct — see *Edge cases*: ```perl sub safe_parse { my ($text) = @_; try { parse($text); } catch ($e) { warn "parse error: $e"; undef; # value of the catch block } } ``` A `catch` block that itself dies — the new exception propagates outward to the next enclosing handler ([`try`](try)/`catch`, [`eval`](eval), or program exit): ```perl try { open_db(); } catch ($e) { cleanup(); die "open_db failed: $e"; # thrown from inside catch } ``` ## Edge cases - **Cannot stand alone.** `catch (VAR) { ... }` without a preceding [`try`](try) block is a syntax error. `catch` is parsed as part of the [`try`](try) construct, not as an independent keyword. - **Exactly one scalar in parentheses.** The parentheses are mandatory, must declare exactly one scalar, and the `my` keyword is implied. `catch { ... }` without parentheses is a syntax error. - **`VAR` is block-scoped.** It exists only inside the `catch` block. A [`finally`](finally) block that follows does **not** see it. - **Falsy exceptions still trigger the handler.** [`try`](try) distinguishes "died" from "completed normally" by a flag set at unwind time, not by truthiness of the exception value. `die 0`, `die ""`, and `die undef` all enter the `catch` block; `VAR` receives the value as thrown (with [`die`](die)'s usual coercion of `undef` to `"Died at ..."`). - **[`$@`](../perlvar) is not set.** Code that reaches for [`$@`](../perlvar) inside a `catch` block is reading the caller's [`$@`](../perlvar), not the exception just caught. Use `VAR`. - **A `catch` block may die.** Exceptions raised from inside `catch` are **not** re-caught by the same construct. They propagate to the next enclosing handler. This is the mechanism for re-throw (`die $e`) and for reporting cleanup failures from the handler itself. - **[`return`](return) inside `catch` returns from the enclosing subroutine**, not from the `catch` block. This differs from [`eval`](eval) BLOCK, where [`return`](return) would leave only the [`eval`](eval). To yield a value *from* the construct, use the block's final expression instead of [`return`](return). - **Loop controls ([`last`](last), [`next`](next), [`redo`](redo)) inside `catch`** target an enclosing loop, not the construct. The [`try`](try)/`catch` construct is not itself a loop. - **`caller()` does not see the `catch` frame.** Because `catch` does not intercept [`return`](return), it is invisible to [`caller`](caller), like `while` or `foreach` are. - **Pairs only with the immediately preceding [`try`](try).** You cannot have two `catch` blocks, nor place statements between [`try`](try) and `catch`. The optional [`finally`](finally) block, if present, must come after `catch`. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`try`](try) — the block whose failure this `catch` handles; always paired with exactly one `catch` - [`finally`](finally) — optional third block that runs regardless of whether the [`try`](try) block died; cannot [`return`](return) or use loop controls - [`die`](die) — produces the exception value that `VAR` receives; use it inside `catch` to re-throw - [`eval`](eval) — older exception-handling idiom using [`$@`](../perlvar); reach for [`try`](try)/`catch` instead in new code for clearer scoping and no [`$@`](../perlvar) footguns - [`$@`](../perlvar) — left untouched by [`try`](try)/`catch`; inspect `VAR` instead