PDO Error Handling
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);
}
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
31 Mar 2026
Views
20
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
No pings yesterday
Perplexity 6
Google 3
Unknown AI 2
ChatGPT 1
Meta AI 1
Ahrefs 1
Also referenced
How they use it
crawler 12
crawler_json 2
Related categories
⚡
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
🔍 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