coffeemonitor
coffeemonitor

Reputation: 13120

Exceptions in PHP - set_exception_handler output

I'm starting to use set_exception_handler now. The first place I tested is the try/catch block for my PDO layer.

I forced an Exception with incorrect database credentials. (this is before I applied the

<?php  

function log_exception($exception){
    print_r($exception);    
}

set_exception_handler("log_exception");

try { 
    $dbh = new PDO();
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    echo "connected!! \n";
} catch (PDOException $e) { 
    print_r($e); // let's see what it looks like
    throw new Exception($e); 
}
?>

You'll see print_r inside the catch, as well as in the log_exception function.

This is what gets displayed from print_r($e):

PDOException Object
(
    [message:protected] => SQLSTATE[28000] [1045] Access denied for user 'localhost'@'127.0.0.1' (using password: YES)
    [string:Exception:private] =>
    [code:protected] => 1045
    [file:protected] => /var/www/html/test.php
    [line:protected] => 35
    [trace:Exception:private] => Array
        (
            [0] => Array
                (
                    [file] => /var/www/html/test.php
                    [line] => 35
                    [function] => __construct
                    [class] => PDO
                    [type] => ->
                    [args] => Array
                        (
                            [0] => mysql:host=127.0.0.1;dbname=db_tests;charset=utf8
                            [1] => test
                            [2] => test
                        )

                )

        )

    [previous:Exception:private] =>
    [errorInfo] =>
)

And this is what gets displayed from print_r($exception) inside the log_error() function:

Exception Object
(
    [message:protected] => exception 'PDOException' with message 'SQLSTATE[28000] [1045] Access denied for user 'localhost'@'127.0.0.1' (using password: YES)' in /var/www/html/test.php:34
Stack trace:
#0 /var/www/html/test.php(34): PDO->__construct('mysql:host=127.0...', 'test', 'test')
#1 {main}
    [string:Exception:private] =>
    [code:protected] => 0
    [file:protected] => /var/www/html/test.php
    [line:protected] => 34
    [trace:Exception:private] => Array
        (
        )

    [previous:Exception:private] =>
)

What are they different? I am assuming that whatever Exception Object is passed into the log_error() function is going to be the same as what got generated within the catch.

Am I missing something?

...

Upvotes: 2

Views: 588

Answers (2)

lshas
lshas

Reputation: 1731

This is because they are two different Exceptions.

As you can see here PDOException has some properties that Exception does not. And what you are doing in the catch is throw a new Exception, with the previous Exception as the message. The Exception constructor expects a string to be passed as message, and will then get the output of the PDOExceptions method __toString. The other properties will be set according to where the last Exception was thrown.

As Cristik said, if you want to pass the Exception along you can just use throw $e. This will pass this Exception to the exception handler.

When you create a new Exception the line and file properties will be set according to where this Exception was instantiated. The trace will also be different. But all these will be kept intact if you just throw the one you caught.

Upvotes: 2

Cristik
Cristik

Reputation: 32771

You should be throwing the same exception if you want to forward it, not a new one:

throw $e;

Upvotes: 3

Related Questions