What im trying to achieve here , is when the pdo connection throws an exception , my custom exception handler takes the message and passes it on so i can catch it with my custom exception handler.
try {
$mysqli = new PDO('mysql:host='.THOST.';dbname='.TDB.'', TUSER, TPASS);
}
catch (PDOException $e) {
$a = $e->getMessage();
throw new customException ( "Failed to connect to MySQL:". $a );
die();
}
catch (customException $e){
echo $e->errorMessage();
}
BUT it returns this error :
Fatal error: Uncaught exception 'customException' with message ......
Wrap it in another try-catch block.
try {
try {
$mysqli = new PDO('mysql:host='.THOST.';dbname='.TDB.'', TUSER, TPASS);
} catch(PDOException $e) {
$a = $e->getMessage();
throw new customException ( "Failed to connect to MySQL:". $a );
}
} catch(customException $e) {
echo $e->errorMessage();
// Do what you want
}
You are confusing custom exception handler with custom exception class. You need the former one and the other answer is wrong.
Explanation.
In your application code you have to writing one single line only:
$pdo = new PDO('mysql:host='.THOST.';dbname='.TDB.'', TUSER, TPASS);
without multiple tries and stuff. Just the code you need to run.
While all the handling logic goes into handler
Related
Is there a way to setup a Pdo object to throw a custom exception instead of the default PDOException?
For example:
class MyCustomDbException extends PDOException{}
$pdo = new Pdo("mysql:host=localhost;dbname=myapp", "user_name", "secret_password");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EXCEPTION_CLASS, "MyCustomDbException");
try {
// Code is here
} catch (PDOException $e) {
// See exception manual if you want to path through message or anything else from pdo exception.
throw new YourException('PDO exception was thrown');
}
http://php.net/manual/en/language.exceptions.extending.php
to see how you can path through parameters.
I have a custom error handlers:
set_error_handler('API_Error_Handler');
register_shutdown_function('Fatal_Error_Handler'); // This one calls API_Error_Handler eventually
In the following example, both catch{} section AND API_Error_Handler are executed.
try{
// Exception raised here
} catch(Exception $e){
// No error reporting needed, do something else
}
I want ONLY catch{} to execute. How do I do that? Maybe determine within API_Error_Handler whether exception is already caught by try-catch? Or are there other approaches available?
Example code:
set_error_handler(function() {
echo "Error is handled by custom error handler. <br>";
});
try{
new SoapClient('http://bad.address/wsdl');
} catch(Exception $e){
echo "Error is caught. <br>";
}
I think the best way will be to create an Exception class by your self that extends Exception:
class MyCustomException extends \Exception {}
and throw this where you need it. Then change
} catch (Exception $e)
to
} catch (MyCustomException $e)
and you should only get your custom exception catched
I have the following script.
According to http://php.net/manual/en/class.pdoexception.php, You should not throw a PDOException from your own code.
But I want the same catch to be performed whether a PDOException or the exception that I threw for an invalid foo.
I've also been told that I should never catch the generic Exception, but only catch specific Exceptions.
How should this be implemented?
try {
db::db()->beginTransaction();
//Do a bunch of queries, and a PDO exception will be thrown upon error
if($foo($bar)) {throw new Exception('Invalid foo.');}
db::db()->commit();
} catch (PDOException $e) {
db::db()->rollBack();
//Maybe do some other stuff
}
Something like
try {
db::db()->beginTransaction();
//Do a bunch of queries, and a PDO exception will be thrown upon error
if($foo($bar)) {throw new RuntimeException('Invalid foo.');}
db::db()->commit();
} catch (PDOException $e) {
db::db()->rollBack();
//Maybe do some other stuff
} catch (RuntimeException $e) {
//foo invalid
}
I have a Database class:
<?php
namespace Database\MySQL;
class Database
{
function __construct(){
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
try {
$this->Connection = new mysqli(
"", // Testing with no host
"", // Testing with no user
"", // ... no password
"" // and no DB name
);
}
catch (mysqli_sql_exception $e) {
throw $e;
}
...
?>
But instead of a getting an exception, I get a Fatal error: Fatal error: Uncaught exception 'mysqli_sql_exception' with message 'No database selected' in Database.php.
I have tried the same thing with a simple query:
try {
$this->Connection->query("SET NAMES 'utf87'"); //utf87 just for test
}
catch (mysqli_sql_exception $e) {
throw $e;
}
And I still get Fatal error: Uncaught exception.
Your problem is that you are catching the exception, but then just throwing it again without catching it.
If you replace throw $e; with echo "Caught the exception";, you will see that your script is catching the exception. But because you throw it again, it will result in an error unless you have a higher-level try/catch block or a global exception handler.
Also, as many have pointed out in the comments, you need to be careful of namespaces. You need to use a use statement or refer to \mysqli_sql_exception.
I'm building a custom exception class to manage all exceptions:
class MyExceptions extends Exception
{
public function __construct($message = 'Unkown errror', $code = -1, Exception $previous = null) {
echo 'init!';
parent::__construct($message, $code, $previous);
}
}
Now, when a PDOException occurs, I want to re-throw it to MyExceptions:
class myDB
{
private $db;
public function dbConnect() {
try {
$this->db = new PDO('mysql:host=localhost;dbname=db;charset=utf8', 'user', 'pass');
}
catch (PDOException $e) {
throw new MyExceptions($e);
}
/* Updated */
catch (MyExceptions $e) {
echo 'caught!';
}
}
}
The problem is that when a db connection exception rises, I get the following fatal error on screen:
init!
Fatal error: Uncaught exception 'MyExceptions' with message...
So, the exception is not caught, although the MyExceptions __construct() is called (see the 'init!' displayed).
Every bit of resource I read points to the exact implementation as mine, I have no idea what I'm doing wrong.
You need
try {
try {
$this->db = new PDO('mysql:host=localhost;dbname=db;charset=utf8', 'user', 'pass');
} catch (PDOException $e) {
throw new MyExceptions($e);
}
} catch (MyExceptions $f) {
echo 'caught!';
}
Sequential catch blocks are for different types of exceptions thrown within the try.
You are throwing it:
throw new MyExceptions($e);
^^^^^
And then you don't catch it. So what do you wonder about?
Also you should add the previous exception at third position (for previous) instead of the first position (for message).
It doesn't go through all the catch blocks. Only the first one that matches. If you then throw another exception inside a catch block, you'd have to catch it in another try block around the first one.