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

PDO Error Handling

PHP PHP 5.1+ Beginner
debt(d5/e1/b5/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5), because the detection_hints list phpstan and semgrep — both specialist static analysis tools — as the means to catch missing ERRMODE_EXCEPTION on PDO construction. The pattern is invisible at runtime in default silent mode, so it won't be caught by a compiler or default linter, but semgrep/phpstan rules can flag the missing attribute.

e1 Effort Remediation debt — work required to fix once spotted

Closest to 'one-line patch or single-call swap' (e1), because the quick_fix is explicitly a single addition to the PDO constructor options array — PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION — which is a one-line change at the point of instantiation.

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

Closest to 'persistent productivity tax' (b5), because PDO is used in both web and cli contexts (per applies_to) and the error handling mode shapes how every database interaction behaves across the codebase. If ERRMODE_SILENT is in effect, every query call site is implicitly affected, and any future maintainer must reason about silent failures. It does not quite reach b7 because fixing it at the construction point is localized, but the reach of the silent failure mode spans many work streams.

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

Closest to 'serious trap — contradicts how a similar concept works elsewhere' (t7), because the misconception is that checking execute() return values is sufficient — a pattern that works in many other DB layers and error-handling paradigms. The default ERRMODE_SILENT actively suppresses errors without any visible signal, directly contradicting the expectation that failed operations surface as errors. Developers familiar with exceptions-by-default frameworks (or other DB drivers) will assume failures are loud, making this a serious behavioral contradiction.

About DEBT scoring →

Also Known As

PDO::ERRMODE_EXCEPTION PDOException PDO error modes

TL;DR

PDO has three error modes — silent, warning, and exception — controlling how database errors surface.

Explanation

PDO::ERRMODE_SILENT (default) suppresses all errors — queries fail silently. PDO::ERRMODE_WARNING triggers PHP warnings. PDO::ERRMODE_EXCEPTION throws PDOException on any database error, enabling try/catch and preventing silent data corruption. Always set ERRMODE_EXCEPTION. PDOException extends RuntimeException and exposes errorInfo() with the SQLSTATE code, driver error code, and driver message.

How It's Exploited

Silent PDO errors allow SQL injection attempts to fail invisibly — attackers can probe without triggering any visible error response.

Common Misconception

Checking return values from execute() is sufficient without ERRMODE_EXCEPTION. execute() returns false on failure but only if you check it every single time — ERRMODE_EXCEPTION enforces error handling automatically.

Why It Matters

ERRMODE_SILENT is the default, meaning failed queries return false with no visible error — bugs become invisible data corruption issues that are extremely hard to diagnose in production.

Common Mistakes

  • Forgetting to set ERRMODE_EXCEPTION — silent failures corrupt data without any visible error.
  • Catching PDOException and swallowing it with an empty catch block.
  • Logging the exception message but not the SQLSTATE or full errorInfo array, losing diagnostic detail.

Avoid When

  • Never expose PDOException messages directly in HTTP responses — they contain table names, column names, and query structure.

When To Use

  • Always set ERRMODE_EXCEPTION immediately after constructing the PDO object.
  • Catch PDOException at the service layer, log the full error, and rethrow as a domain exception.

Code Examples

✗ Vulnerable
// ERRMODE_SILENT — default — fails invisibly
$pdo = new PDO($dsn, $user, $pass);
$stmt = $pdo->prepare('INSERT INTO orders VALUES (?, ?)');
$stmt->execute([$userId, $total]); // returns false silently on error
// $total was never saved — you'll never know
✓ Fixed
$pdo = new PDO($dsn, $user, $pass, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);

try {
    $stmt = $pdo->prepare('INSERT INTO orders (user_id, total) VALUES (?, ?)');
    $stmt->execute([$userId, $total]);
} catch (PDOException $e) {
    // Log full error detail — never expose to user
    error_log('DB error: ' . $e->getMessage() . ' SQLSTATE:' . $e->getCode());
    throw new RuntimeException('Order could not be saved', 0, $e);
}

Added 31 Mar 2026
Views 46
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 1 ping W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 1 ping W 1 ping T 0 pings F 3 pings S 3 pings S 1 ping M 0 pings T 0 pings W 0 pings T 2 pings F 0 pings S 0 pings S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 1 ping W
Claude 1
No pings yesterday
Perplexity 6 Scrapy 6 Google 5 Ahrefs 3 SEMrush 3 Unknown AI 2 Meta AI 2 Claude 2 ChatGPT 1 Majestic 1 PetalBot 1
crawler 29 crawler_json 3
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Low
⚡ Quick Fix
Set PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION in the PDO constructor options — never rely on the default silent mode
📦 Applies To
PHP 5.1+ web cli
🔗 Prerequisites
PDO
🔍 Detection Hints
new PDO(...) without PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
Auto-detectable: ✓ Yes phpstan semgrep
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Low ✓ Auto-fixable Fix: Low Context: Line


✓ schema.org compliant