How to handle PDO exceptions
PDO won't throw exceptions unless you tell it to. Have you run:
$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
on the PDO object?
PDO Exception Questions - How to Catch Them
You should look at the documentation. But If you dont find anything, you can add another catch :
<?php
try {
$stmt = $db->prepare("INSERT INTO tbl_user (id, name, password, question, answer) VALUES (NULL, :name, :password, :question, :answer)");
$stmt->bindValue(":name", $_POST['name']);
$stmt->bindValue(":password", $_POST['password']);
$stmt->bindValue(":question", $_POST['question']);
$stmt->bindValue(":answer", $_POST['answer']);
$stmt->execute();
echo "Successfully added the new user " . $_POST['name'];
} catch (PDOException $e) {
echo "DataBase Error: The user could not be added.<br>".$e->getMessage();
} catch (Exception $e) {
echo "General Error: The user could not be added.<br>".$e->getMessage();
}
?>
This must work because all exceptions of PHP plugins herits from the Exception native PHP class. (Since 5.0 if my memory is well).
How to handle PDO connection errors properly?
Your current code has some flaws. Let me give you few pointers.
You do not need the function you have created, at least not in the current form. Every time you call this function it creates a new PDO object, which can hinder your script's performance. Ideally you would want to have only one connection throughout the execution of your whole script.
When creating new PDO connection you need to remember 3 things: to set proper connection charset, enable error reporting, and disable emulated prepares.
- Proper charset is important. Without it your data could get corrupted or even leave you vulnerable to SQL injection. The recommended charset is
utf8mb4
. - Enabling error reporting saves you the trouble of manually checking every single function call for failures. You just need to tell PHP to trigger exceptions when an error occurs and find a suitable way of logging the errors on your server (read more: My PDO Statement doesn't work)
- Emulated prepares are enabled by default, but the truth is you are better off without them. If your database supports native prepared statements, and most do, then use them instead.
The full code should look something like this:
$options = [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_EMULATE_PREPARES => false,
];
$pdo = new \PDO('mysql:host=localhost;dbname=dbname;charset=utf8mb4', 'user', 'pw', $options);- Proper charset is important. Without it your data could get corrupted or even leave you vulnerable to SQL injection. The recommended charset is
Don't catch the exceptions unless you know what to do with them and are positively sure you need to do so. Exceptions are best left be; let PHP handle them together with the other exceptions/errors/warnings. After all why make an exception just for PHP exceptions? All PHP errors should be handled the same. Whatever you do never print (including
die
,exit
,echo
,var_dump
) the error message manually on the screen. This is a huge security issue if such code ever makes its way into production.
If your PDO connection is set to throw exceptions on errors, you never need to use if
statements to check return code of prepare()
or execute()
.
How can I get both PDO exceptions and the other ones?
You can use multiple catch blocks
catch(PDOException $pdo) {
echo $pdo;
}
catch(Exception $e) {
echo $e;
}
Or you can still keep one catch block and take help from instanceof
catch(Exception $e) {
if($e instanceof PDOException)
// pdoexception
else
// others
}
Laravel handle PDO Exception message
I hope it helps
if ($exception instanceof \PDOException && Str::contains($exception->getMessage(), '(SQL:')) {
dd(Str::before($exception->getMessage(), '(SQL:'));
}
Printed SQLSTATE[HY000]: General error: 1364 Field 'name' doesn't have a default value
for me
Logging PDO exception to error_reporting and error_log
It turns out that I need to override the exception handler which is independent from error handler. So I need to forward the exceptions to error handler. Theoretically, the following should be implemented.
<?php
function exception_handler($exception) {
echo "Uncaught exception: " , $exception->getMessage(), "\n";
error_log(.....$exception->getMessage().....); //Yay it goes to my file now
}
set_exception_handler('exception_handler');
throw new Exception('Uncaught Exception');
echo "Not Executed\n";
?>
Research further here
Related Topics
C#'s Null Coalescing Operator () in PHP
How to Keep JSON_Encode() from Dropping Strings with Invalid Characters
Encryption/Decryption of Form Fields in Cakephp 3
PHP - Plus Sign with Get Query
Which Line Break in PHP Mail Header, \R\N or \N
Check If a Row Exists Using Old MySQL_* API
Handling Big User Ids Returned by Fql in PHP
Which Is the Best Way to Generate Excel Output in PHP
Convert a String into an Array of Characters
How to Set a Default Attribute Value for a Laravel/Eloquent Model
How to Get All Captures of Subgroup Matches with Preg_Match_All()
Get Text from <Option> Tag Using PHP
Implicit Class Variable Declaration in PHP
Type-Juggling and (Strict) Greater/Lesser-Than Comparisons in PHP