Question

Silex seems to hijack the exceptions thrown anywhere in the app. My problem with this is I have a user_db_interface class I use to pass/get user data from my database that is basically ignored once an exception is thrown.

For example if I have a duplicate user email entry that generates a PDOException, instead of being able to handle that exception within my class, I have to add an error handling closure outside of my class. I'd rather deal with the exception internally so that I can act on this exception and continue with my script.

Any such thing as an exception override or bypass?

Here is an example:

###### PROVIDER REG #######
// I'M LOADING DOCTRINE "NATURALLY" AND NOT REGISTERING IT WITH $APP IN HOPES OF 
// AVOIDING THE EXCEPTION HIJACKING.
################################################################### LOAD DOCTRINE NATURAL

require 'vendor/Doctrine/Common/ClassLoader.php';

$classLoader = new \Doctrine\Common\ClassLoader('Doctrine', __DIR__ . '/../vendor');
$classLoader->register();

$connectionOptions = array(
    'driver'    => 'pdo_mysql',
    'dbname'    => 'MY_DB',
    'host'      => 'localhost',
    'password'  =>  'MY_PASS',
    'user'      => 'MY_USER',
);

$driver = new \Doctrine\DBAL\Driver\PDOMySql\Driver;
$connection = new \Doctrine\DBAL\Connection($connectionOptions, $driver);

###################################################################### LOAD MY EXTENSION
$app['autoloader']->registerNamespaces(array('TableTrackPro' => __DIR__,));

$app->register(new TableTrackPro\ClientDBInterfaceExtension(),array('app'=>$app));
$app['client_db_interface']->set_connection($connection);


##################################################
##################################################

#################################################  MY DB INTERFACE CLASS (stripped for clarity)

namespace TableTrackPro;

class ClientDBInterface{

    private $_connection;

    public function set_connection($connection){
        $this->_connection = $connection;
    }

    public function insert_client($clientInfo){
        // SET RETURN OBJECT
        $returnObject['status'] = 'ok';     // default return status
        $returnObject['message'] = false;


// SANITIZE CLIENT INFO ETC...

 // THIS IS WHERE I WOULD LIKE TO HANDLE MY OWN EXCEPTIONS
    try{
        $this->_connection->insert('clients', $clientInfo);
    }catch(PDOException $e){
       // HANDLE EXCEPTION HERE
    }
    return json_encode($returnObject);
}


#### END CLASS #####


### CONTROLLERS ####

$app->post('/postNewClient', function () use($app){
    $clientInfo = $_POST;
    $returnObject = $app['client_db_interface']->insert_client($clientInfo);
    return json_encode($returnObject);  // <-- I handle this object with javascript via an AJAX call
});

Instead of handling the PDOException in my class so that I can return data as I wish, I have to add an error handler to the controller area like:

$app->error(function (\Exception $e, $code) {
   // error handling code, I'd now have to handle any client-db specific errors outside of my client_db class...
});

I'd like to avoid this because if the exception handling were internal to the client_db class, I would know that the error was also specific to that action and I wouldn't have to write an error parser.

Was it helpful?

Solution

Alright, so the only thing silex does is catch the exception during the $app->run() call. There is nothing in there preventing you from catching the exception yourself earlier.

I suspect that your issue is caused by the following. Assuming your code is actually:

try{
    $this->_connection->insert('clients', $clientInfo);
}catch(PDOException $e){
   // HANDLE EXCEPTION HERE
}

Well, the issue is that you're in a namespaced class. This means that all class names are relative to the current namespace. To reference the global namespace you need to use them or prefix them with \.

What you need to do is:

try{
    $this->_connection->insert('clients', $clientInfo);
}catch(\PDOException $e){
   // HANDLE EXCEPTION HERE
}

Does this solve your problem?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top