Cphalcon: Impossible catch of PDOException

Created on 7 Apr 2013  Â·  4Comments  Â·  Source: phalcon/cphalcon

The short explanation.
This code:

try {
    $db = new Db\Adapter\Pdo\Mysql($unavailable_database);
} catch (PDOException $e) {
    echo 'ops...';
}

cause this:

Warning: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [2002] 'Can't connect to [... and blablabla]

The long explanation.
By default, exceptions of PDO doesn't caught by php (even with help of set_exception_handler()). But they could if error mode is an exceptions mode:

$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

And to catch connection problems this attribute must be set before connection.

The problem is that Phalcon calls connection directly in the constructor of Phalcon\Db\Adapter\Pdo*
So the trick like

$db = new Db\Adapter\Pdo\Mysql($params);
$db->getInternalHandler()->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

doesn't work and it becomes impossible to catch PDOException thrown while connecting.
It's really sad, because uncaught exceptions just ruins the application, you even can't print some 'Sorry, connection problems...'.

Most helpful comment

I added a new parameter options to Phalcon\Db\Adapter\Pdo to pass PDO parameters before the connection:

$db = new Db\Adapter\Pdo\Mysql(array(
    'username' => 'root', 
    'password' => 'hello',
    'dbname' => 'test',
    'options' => array(
         PDO::ATTR_TIMEOUT => 5
    )
));

This is in the 1.1.0 branch

All 4 comments

I assume you're running something like this: https://gist.github.com/phalcon/5328034

As you can see no warnings are generated: http://test.phalconphp.com/pdo.php

If you have that inside a namespace you need to prepend a namespace separator to the PDOException

} catch (\PDOException $e) {

Hm... seems like more details appeared after your example.
I set max exec time in php to 10 sec. In my case I used unavailable port to connect. Seems like exception become uncaught because of interrupted performance after 10 sec. — the timeout for PDO connection trying is ~20 sec.
Yeah, all this make sense now...
Now the problem isn't so serious.

Can I somehow change timeout for Phalcon\Db\Adapter\Pdo\Mysql?
I just think that 30 seconds is too long for user-side php, on my server all of the enduring scripts use separated cli-php with it's own setting.

I added a new parameter options to Phalcon\Db\Adapter\Pdo to pass PDO parameters before the connection:

$db = new Db\Adapter\Pdo\Mysql(array(
    'username' => 'root', 
    'password' => 'hello',
    'dbname' => 'test',
    'options' => array(
         PDO::ATTR_TIMEOUT => 5
    )
));

This is in the 1.1.0 branch

Thanks! Phalcon becomes better every day =)

Was this page helpful?
0 / 5 - 0 ratings