Solved thread

This post is marked as solved. If you think the information contained on this thread must be part of the official documentation, please contribute submitting a pull request to its repository.

Handling database errors

Hello!

I am working on a Phalcon project (of course!) and have been dealing with models, I don't know how to handle the database errors, though.

if (!$user->save()) {
   //
}

Code like this (^) is supposed to handle all errors, like? but the foreign key violations lead to errors like:

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '[email protected]' for key 'email'


11.1k
Accepted
answer

Hi !

    try{
        if(!$user->save()){
            $errors = $user->getMessages();
        }
    } catch(PDOException $e){
        $error = $e->getMessage();
    }
edited Dec '17

With PHP7 it's easy to catch every possible exception type:

catch (\Throwable $t){
    $thrown = get_class($t);
    echo "$thrown: {$t->getMessage()} ({$t->getCode()})" . PHP_EOL;
    //print_r($t->getTrace()); //debug only
    //echo $t->getTraceAsString(); //debug only

    //exit takes only integer args in the range 0 - 255
    $exitStatus = $t->getCode() > 0xff ? 0xff : $t->getCode();

    exit($exitStatus);
}

Of course if you need/have sparate exception handling between PDO (DB) and other errors, then simply chainload them. Also, remove exit calls as this is my example used for CLI only, thus I needed exit code.

You should add Uniqueness validator to your model.



85

You should add Uniqueness validator to your model.

Does the validator avoid a race condition between doing a select to test for existence and an insert? When looking at this a few years back there didn't seem to be any such avoidance.

You can use model validation



85

You can use model validation

How does that avoid a race condition? Unless it's changed, Phalcon wouldn't lock and would simply do a select followed by an insert if a row for the given model didn't already exist, so between the select and insert, an insert could be performed from another connection and cause a potential duplicate. Was wondering if that approach had changed. The only safe way seems to be a DB constraint.