PDO Errors handler

Hi!

I am using custom container for PDO:

$container['db'] = function ($c) {
    $db = $c['settings']['db'];
    $pdo = new PDO("mysql:host=" . $db['host'] . ";dbname=" . $db['dbname'],
        $db['user'], $db['pass']);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
    return $pdo;
};

And in group:

$this->post('/create', function ($request, $response, $args) {
    $lectureToCreate = $request->getParsedBody();
    
    $sth = $this->db->prepare("INSERT INTO lectures (name, surname, username, password) VALUES (?, ?, ?, ?)");
    $sth->execute([$lectureToCreate['name'], $lectureToCreate['surname'], $lectureToCreate['username'], password_hash($lectureToCreate['password'], PASSWORD_DEFAULT)]);
    
    echo "Created Lector";
});

Hovewer I have many reguest and each use PDO. Do try-catch for each and send some error? No logic.

Which the best way to handle database errors?

What do you want to do with the caught exception? The standard Slim ErrorHandler will catch them.

1 Like

Really? If I have some database error, it generate error response?
May you give some link or more info?

Given this Slim application:

<?php
$settings = [
    'settings' => [
        'displayErrorDetails' => true,
    ],
];
$app = new \Slim\App($settings);

$container = $app->getContainer();

$container['db'] = function ($c) {
    $db = $c['settings']['db'];
    $pdo = new PDO("mysql:host=" . $db['host'] . ";dbname=" . $db['dbname'],
        $db['user'], $db['pass']);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
    return $pdo;
};

$app->get('/', function ($request, $response, $args) {
    $this->db->query("select * from users");
});


$app->run();

I get this display: https://i.19ft.com/441b4755.png

1 Like

Yep. But I am using AngularJS and Slim is only backend api service. And above all for me is necessary to receive some JSON with error “message” field with info when error occurred.

Thanks!

Set your Accept header correctly:

$ curl -H "Accept: application/json" http://localhost:8888
{
    "message": "Slim Application Error",
    "exception": [
        {
            "type": "PDOException",
            "code": 1045,
            "message": "SQLSTATE[HY000] [1045] Access denied for user ''@'localhost' (using password: NO)",
            "file": "\/www\/dev\/slim3\/develop-testbed\/public\/index-pdo-error.php",
            "line": 14,
            "trace": [
                "#0 \/www\/dev\/slim3\/develop-testbed\/public\/index-pdo-error.php(14): PDO->__construct('mysql:host=;dbn...', NULL, NULL)",
                "#1 \/www\/dev\/slim3\/develop-testbed\/vendor\/pimple\/pimple\/src\/Pimple\/Container.php(112): {closure}(Object(Slim\\Container))",
                "#2 \/www\/dev\/slim3\/develop-testbed\/lib\/Slim\/Slim\/Container.php(123): Pimple\\Container->offsetGet('db')",
                "#3 \/www\/dev\/slim3\/develop-testbed\/lib\/Slim\/Slim\/Container.php(170): Slim\\Container->get('db')",
                "#4 \/www\/dev\/slim3\/develop-testbed\/public\/index-pdo-error.php(21): Slim\\Container->__get('db')",
                "#5 [internal function]: Closure->{closure}(Object(Slim\\Http\\Request), Object(Slim\\Http\\Response), Array)",
                "#6 \/www\/dev\/slim3\/develop-testbed\/lib\/Slim\/Slim\/Handlers\/Strategies\/RequestResponse.php(41): call_user_func(Object(Closure), Object(Slim\\Http\\Request), Object(Slim\\Http\\Response), Array)",
                "#7 \/www\/dev\/slim3\/develop-testbed\/lib\/Slim\/Slim\/Route.php(325): Slim\\Handlers\\Strategies\\RequestResponse->__invoke(Object(Closure), Object(Slim\\Http\\Request), Object(Slim\\Http\\Response), Array)",
                "#8 \/www\/dev\/slim3\/develop-testbed\/lib\/Slim\/Slim\/MiddlewareAwareTrait.php(116): Slim\\Route->__invoke(Object(Slim\\Http\\Request), Object(Slim\\Http\\Response))",
                "#9 \/www\/dev\/slim3\/develop-testbed\/lib\/Slim\/Slim\/Route.php(297): Slim\\Route->callMiddlewareStack(Object(Slim\\Http\\Request), Object(Slim\\Http\\Response))",
                "#10 \/www\/dev\/slim3\/develop-testbed\/lib\/Slim\/Slim\/App.php(441): Slim\\Route->run(Object(Slim\\Http\\Request), Object(Slim\\Http\\Response))",
                "#11 \/www\/dev\/slim3\/develop-testbed\/lib\/Slim\/Slim\/MiddlewareAwareTrait.php(116): Slim\\App->__invoke(Object(Slim\\Http\\Request), Object(Slim\\Http\\Response))",
                "#12 \/www\/dev\/slim3\/develop-testbed\/lib\/Slim\/Slim\/App.php(337): Slim\\App->callMiddlewareStack(Object(Slim\\Http\\Request), Object(Slim\\Http\\Response))",
                "#13 \/www\/dev\/slim3\/develop-testbed\/lib\/Slim\/Slim\/App.php(298): Slim\\App->process(Object(Slim\\Http\\Request), Object(Slim\\Http\\Response))",
                "#14 \/www\/dev\/slim3\/develop-testbed\/public\/index-pdo-error.php(25): Slim\\App->run()",
                "#15 \/www\/dev\/slim3\/develop-testbed\/public\/index.php(15): include('\/www\/dev\/slim3\/...')",
                "#16 {main}"
            ]
        }
    ]

Override the error handler if you want more control: http://www.slimframework.com/docs/handlers/error.html

1 Like

Cool! Thanks you very much!

This is still not what I expect to have as a error message. Like my friend who posted that, I work with angularjs and I would like to receive other error message. Display it for user who have no knowledge about web programming.
Exapmle:

{
status: FALSE,
message: “Database error: wrong hostname or database name or username. Use db setup to init connection” // etc
}

I tried use:
try {
$pdo = new \Slim\PDO\Database($dsn, $usr, $pwd, $options);
} catch (PDOException $e) {
echo 'Connection failed: ’ . $e->getMessage();
//if it start work, I will format that with json correctly…
}

but all time I get:
Slim Application Error
A website error has occurred. Sorry for the temporary inconvenience.