What standard is used to treat SQLSTATE in Pdoexception?

Asked

Viewed 140 times

2

I don’t know if I’m the one who didn’t understand how the SQLSTATE, however in MySQL many errors do not have a SQLSTATE, and when I take the Exception of PDO, the code that is returned to me is the SQLSTATE instead of the error code that is proper to the database driver.

The application I am working on will not use other banks, so I see no problem in getting the driver code, but the question that intrigues me is that by default the ::PDOException->getCode() returns a SQLSTATE, then it must be used a lot, but I didn’t understand how, since it is ambiguous.

Example: Let’s assume that I have a class that does common procedures and only needs to return messages to the user, if it worked out, or if it did and the reason why.

To avoid the same code, I would have a method that does the handling of these exceptions, receiving Exception, where the method will see what its type and its error code, and return me a standard message.

If the returned SQLSTATE code was 23000, where it is returned in Insert, delete, update operations that have integrity issues, fields that cannot be null, and a variety of other things, how would I distinguish and deliver the correct message?

I made an implementation of the example.

public function remover()
{
    ids = filter_input(INPUT_POST, 'checkbox', FILTER_SANITIZE_STRING, FILTER_REQUIRE_ARRAY);
    try
    {
        $this->con->beginTransaction();
        $cidadeDao = new CidadeDao($this->con);
        $n = $cidadeDao->delete($ids, $this->usuario);
        $this->con->commit();
        $this->response['message'] = "$n cidades foram excluídas com sucesso";
        $this->response['rows'] = $n;
    } 
    catch (Exception $ex) 
    {
        $this->handleResponseException($ex);
    }

    $this->view->renderJSON($this->response);
}

And an Handler to handle these common exceptions and just return an error message (in which case I don’t need to treat anything, it’s just the same message)

protected function handleResponseException(Exception $ex)
{
    $this->response['error'] = true;

    switch( get_class($ex) )        
    {
        case 'UnexpectedValueException':
            // ..
        break;

        case 'PDOException':

            try { $this->con->rollBack(); }
            catch (Exception $ex) { /** ... **/ }

            switch( (int) $ex->getCode() )
            {
                case 1022: 
                    $this->response['message'] = "Registro duplicado";
                break;

                case 1451:
                    $this->response['message'] = "Há registros relacionados"
                break;

                default:
                    $this->response['message'] = "Ocorreu um erro na consulta com o banco de dados";
                break;
            }    
        break;
    }    
}

Assuming that the $ex->getCode() return me the driver code, I would know which message to deliver, but it returns a SQLSTATE, how I will distinguish this by the ambiguity of the codes?

Is there any pattern to doing this, or what I’m doing might be considered bad practice (in my view it solves the problem and avoids code, but I don’t know if it would be right).

  • 1

    Within the catch Wouldn’t it be better to take the information 'who knows' (Pdostatement or PDO) than Exception? or the result is the same? I suggest you pass the result of errorInfo() at the throw you must have at delete() for handleResponseException, the specific error is in the key 1 array.

  • If I exchange the $ex->getCode() part for $ex->errorInfo[1] as suggested, I can get the specific error code, I believe I will use it this way. But what intrigued me was the issue of SQLSTATE being ambiguous, so it led me to question whether I’m really doing it right, and not a "gambit".

  • sqlstate is as if it were the category of error ex authentication, generic flaws etc. Ahhh cool, wasn’t sure if the excetion had the method errorInfo(), so(passing through) simplifies more. :)

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.