← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Exception Handling (try/catch/finally)

php PHP 5.0+ Intermediate
debt(d5/e3/b5/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). The detection_hints list phpstan, psalm, and phpcs as the tools that catch the common misuse patterns (empty catch blocks, catch-all swallowing). These are static analysis / specialist tools, not the compiler or a default linter, so d5 is the right anchor. The misuse can persist undetected in production if these tools are not run.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix is to replace broad catch clauses with specific exception types and restructure catch hierarchies — a pattern replacement within one component or file. It is more than a one-line patch (requires identifying all catch sites and deciding what to handle vs. propagate) but does not require cross-file or architectural rework in typical cases.

b5 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b5). Exception handling applies across web, cli, and queue-worker contexts (all three listed in applies_to), meaning every future maintainer working in any context must reason about the exception hierarchy and propagation strategy. A poorly structured hierarchy (or catch-all swallowing) imposes ongoing cognitive overhead on every error-handling decision, touching many work streams without necessarily defining the entire system's shape.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception field states explicitly that catch (Exception $e) is widely believed to catch all PHP errors, but PHP 7+ separates Error from Exception under Throwable — TypeError, ArithmeticError, and ParseError all escape. This contradicts how exception catching works in many other languages (Java, Python, C#) where the base exception class does catch everything, making it a cross-language expectation violation that competent developers routinely fall into.

About DEBT scoring →

Also Known As

PHP try catch exception hierarchy PHP Throwable interface

TL;DR

PHP's structured error handling mechanism that separates error-path code from the happy path and ensures resource cleanup.

Explanation

PHP exceptions should be used for exceptional, unrecoverable conditions — not for flow control. Catch specific exception types rather than the base Exception or Throwable, use finally blocks for guaranteed resource cleanup (closing files, releasing locks), and never swallow exceptions silently in an empty catch block. PHP 8.0 introduced non-capturing catches (catch (ExceptionType)) when the exception object itself isn't needed. Custom exception hierarchies help callers handle different error categories appropriately.

Diagram

flowchart TD
    TRY[try block executes] --> THROWS{Exception thrown?}
    THROWS -->|no| FINALLY[finally block runs]
    THROWS -->|yes| CATCH{Matching catch?}
    CATCH -->|yes - specific type| HANDLE[Handle exception<br/>log recover rethrow]
    CATCH -->|no match| PROPAGATE[Propagate up call stack]
    HANDLE --> FINALLY
    PROPAGATE --> FINALLY
    FINALLY --> DONE[Continue or halt]
    subgraph Hierarchy
        THROWABLE[Throwable]
        ERROR2[Error - engine errors]
        EXCEPTION[Exception - app errors]
        THROWABLE --> ERROR2 & EXCEPTION
    end
style HANDLE fill:#238636,color:#fff
style PROPAGATE fill:#d29922,color:#fff
style FINALLY fill:#1f6feb,color:#fff

Common Misconception

catch (Exception $e) catches all PHP errors. PHP 7+ separates exceptions (Exception) from engine errors (Error) — both extend Throwable. Catching Exception misses TypeError, ArithmeticError, and ParseError. Use catch (Throwable $e) only when you truly need to catch everything.

Why It Matters

Exceptions provide a structured, unforgeable signal that something went wrong — they cannot be accidentally ignored the way return codes can. Proper exception hierarchies let callers handle errors at the right level of abstraction.

Common Mistakes

  • Catching \Exception or \Throwable everywhere and swallowing it — silent failure is worse than a crash.
  • Using exceptions for normal control flow (throwing to exit a loop) — exceptions are for exceptional situations.
  • Not creating domain-specific exception classes — catching RuntimeException tells callers nothing useful.
  • Logging the exception and rethrowing without passing the original as $previous — you lose the stack trace chain.

Code Examples

✗ Vulnerable
// Catching the base Exception hides bugs; empty catch silences everything
try {
    $this->processOrder($order);
} catch (\Exception $e) {
    // do nothing — you'll never know what went wrong
}
✓ Fixed
try {
    $this->processOrder($order);
} catch (InsufficientStockException $e) {
    return response()->json(['error' => 'Item out of stock'], 409);
} catch (PaymentDeclinedException $e) {
    $this->logger->warning('Payment declined', ['order' => $order->id]);
    return response()->json(['error' => 'Payment failed'], 402);
} catch (\Throwable $e) {
    $this->logger->error('Unexpected error', ['exception' => $e]);
    throw $e; // rethrow — let global handler deal with it
}

Added 13 Mar 2026
Edited 22 Mar 2026
Views 208
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 11 pings S 6 pings S 2 pings M 2 pings T 5 pings W 6 pings T 9 pings F 5 pings S 11 pings S 2 pings M 5 pings T 0 pings W
No pings yet today
ChatGPT 3 Scrapy 1 Qwen 1
ChatGPT 67 Google 27 Scrapy 23 Perplexity 12 Amazonbot 7 Ahrefs 4 SEMrush 4 Unknown AI 2 Majestic 1 Claude 1 Meta AI 1 DuckDuckGo 1 Qwen 1
crawler 146 crawler_json 5
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Medium
⚡ Quick Fix
Catch specific exception types not \Exception or \Throwable at every level; let domain exceptions propagate, catch only what you can handle
📦 Applies To
PHP 5.0+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
catch (\Exception $e) {} empty catch or catch-all swallowing exceptions without logging
Auto-detectable: ✓ Yes phpstan psalm phpcs
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: High ✗ Manual fix Fix: Medium Context: Function Tests: Update
CWE-390 CWE-391

✓ schema.org compliant