For most PHP applications, use PDO::ERRMODE_EXCEPTION and handle PDOException at a boundary where your application can log the failure, roll back work if needed, and return an appropriate response. Exception mode has been PDO’s default since PHP 8.0. If you maintain silent-mode code, inspect the error on the PDO handle or statement that actually performed the failing operation; warning mode is deprecated as of PHP 8.5.
Choose a PDO error mode
PDO provides three error modes. The default depends on the PHP version: silent mode was the default before PHP 8.0, while exception mode has been the default since PHP 8.0. Set the mode explicitly when you want the code to make its intent clear across environments.
| Mode | What happens on an operation error | When it makes sense |
|---|---|---|
PDO::ERRMODE_EXCEPTION |
PDO throws a PDOException. The exception contains or relates to SQLSTATE and driver-specific details. |
Recommended for most modern application code; failures can be handled at a meaningful application boundary. |
PDO::ERRMODE_SILENT |
PDO does not emit a warning or throw for the operation error. The caller must inspect return values and the relevant object’s error state. | Use only when explicit, deliberate per-call error handling is part of the code. |
PDO::ERRMODE_WARNING |
PDO emits an E_WARNING and maintains error state. An installed error handler may change how that warning behaves. |
Legacy code only. This mode is deprecated as of PHP 8.5; avoid it in new code. |
PHP’s error-handling documentation identifies exception mode as the default beginning with PHP 8.0. The PHP 8.5 deprecations RFC records warning mode’s deprecation and points developers toward silent mode with explicit checks or exception mode.
Set exception mode explicitly if useful
$pdo = new PDO($dsn, $username, $password, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
This setting makes the intended behavior visible. It does not prevent connection errors: PDO::__construct() always throws a PDOException when a connection attempt fails, regardless of the configured error mode. Since construction itself can fail, create the connection inside the startup or request-level error boundary responsible for handling that failure.
Recommended Free Tools
#1 Best Overall
Catch exceptions where the application can act
Exception mode avoids manually checking every operation’s return value. Catch a PDOException where the code can recover, roll back a transaction, translate the failure into an application error, or log the details before the request fails. Catching every exception immediately around each query—or swallowing an exception without taking action—can hide failures rather than handle them.
try {
$stmt = $pdo->prepare('UPDATE accounts SET status = :status WHERE id = :id');
$stmt->execute(['status' => 'active', 'id' => $accountId]);
} catch (PDOException $e) {
// Log diagnostic details through the application's protected logging path.
// Return an appropriate application-level response, or rethrow if this
// layer cannot handle the failure meaningfully.
throw $e;
}
Do not expose raw database messages to public users. They are diagnostic information for appropriately protected logs; the user-facing response should be suitable for the application.
Rank #2
Read diagnostics from the object that failed
PDO diagnostics are tied to the object that performed the operation. Use PDO::errorInfo() or PDO::errorCode() for an operation performed directly on the connection handle. For a prepared or queried statement, use that PDOStatement object’s methods. Checking the wrong object can return stale or unrelated information.
errorCode()returns the SQLSTATE value.errorInfo()returns an array containing SQLSTATE, a driver-specific code, and a driver-specific message.
SQLSTATE is the standardized diagnostic layer; the native code and message depend on the database driver. Prefer SQLSTATE or documented driver codes over logic that relies only on matching message text. See the PHP references for PDO::errorInfo() and PDOStatement::errorInfo().
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Handle silent-mode errors deliberately
In silent mode, check the return value and, when it signals failure, inspect the object that ran the operation. For example, a statement failure should be diagnosed through the statement:
$stmt = $pdo->prepare($sql);
if (!$stmt->execute($params)) {
$info = $stmt->errorInfo();
// Handle or log SQLSTATE, driver code, and driver message appropriately.
}
Return-value contracts differ by method. In particular, PDO::exec() can return an affected-row count or false on failure when silent handling is in use. Compare strictly with false; a successful operation affecting zero rows is not itself an error.
Rank #4
$affected = $pdo->exec($sql);
if ($affected === false) {
$info = $pdo->errorInfo();
// Handle or log the connection-handle error.
}
Consult the PHP references for PDO::exec() and PDO::errorInfo() when maintaining this style of handling.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Roll back transactions when work fails
For related database operations that should succeed or fail together, begin a transaction, commit after all work succeeds, and roll back when an exception interrupts the work. Check whether the transaction is active before rolling back: rollBack() throws if there is no active transaction, which could otherwise obscure the original failure.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemstry {
$pdo->beginTransaction();
// Perform related database work.
$pdo->commit();
} catch (PDOException $e) {
if ($pdo->inTransaction()) {
$pdo->rollBack();
}
// Log diagnostic details securely and handle the failure at this boundary.
throw $e;
}
PDO documents automatic rollback on script termination when a transaction was started with beginTransaction() and not explicitly committed. Do not assume the same behavior for a transaction started by issuing a manual transaction command. Transaction support and rollback behavior depend on the driver and database; some databases implicitly commit DDL statements such as CREATE TABLE or DROP TABLE, so those changes may not be undone as expected. See PHP’s documentation on transactions and PDO::rollBack().
Diagnose “PDO is not throwing an exception”
- Check the runtime version. Silent mode was the default before PHP 8.0. Legacy applications may still depend on it because they never set an error mode explicitly.
- Check the configured mode. A connection may have been configured for silent mode, in which case inspect the failing object’s error state and return value.
- Check which operation failed. A connection attempt is a special case: the constructor throws on failure regardless of
PDO::ATTR_ERRMODE. - Check the correct object. Statement errors belong to the
PDOStatement; direct handle operations belong toPDO. - Check the method’s return contract. For
exec(), zero affected rows can be a successful result; test forfalsestrictly in silent-mode code. - Review warning-mode behavior. Warning mode emits
E_WARNING, and an application error handler may promote warnings into exceptions. Because the mode is deprecated in PHP 8.5, migrate rather than depending on this interaction.
The PDO error-handling manual, PDOException reference, and PDO constants reference document the relevant behavior and version annotations.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




