odan / slim4-skeleton

A Slim 4 Skeleton
https://odan.github.io/slim4-skeleton/
MIT License
449 stars 80 forks source link

How to handle query error ? #91

Closed well-it-wasnt-me closed 2 years ago

well-it-wasnt-me commented 2 years ago

Hi, thanks for the amazing work, this skeleton and your book are really something. Just one question...as the title say...how do you handle query insert/general error ?

odan commented 2 years ago

I handle this by catching the exception. For example, when I start a database transaction, I roll it back if an exception occurs.

See here: Transaction

To catch and render all other kind of (database and application) errors, I configured the Slim ErrorMiddleware to use a custom DefaultErrorHandler that renders the Exception into a proper HTTP JSON response.

https://github.com/odan/slim4-skeleton/blob/master/src/Handler/DefaultErrorHandler.php https://github.com/odan/slim4-skeleton/blob/master/config/middleware.php

well-it-wasnt-me commented 2 years ago

yes im using the transactions.

and the try/catch too.

but in this case the insert doesnt trigger the exception but yet its not done.

try {
          $id_dog = $this->queryFactory->newInsert('dogs', $row)->execute()->lastInsertId();
          // THIS GET CALLED
          if (!$id_dogs) {
              $this->transaction->rollback();
              return ['status' => 'error', 'message' => Definition::ERR_ADD_DOG];
          }

      } catch (\Exception $e){
         // THIS NOT
          echo $e->getMessage();
      }

how can i "debug" this and understand why it fails ?

odan commented 2 years ago

It looks like the lastInsertId returns a new ID. So the query might work.

Make sure to enable exception for the database connection.

PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,

You also don't need to check for !$id_dogs then because if something was wrong, the Exception should be thrown anyway.

Also make sure to commit the transaction. Otherwise the insert command changes nothing and the transaction will be reverted at the end.

Example:

use Exception;
// ...

try {
    $this->queryFactory->newInsert('dogs', $row)->execute();
    $this->transaction->commit(); // <--- this is needed
} catch (Exception $e){
    $this->transaction->rollback();
    // Optional log error here
    // ...
}

Edit: Note that a transaction makes only sense when you have a bunch of queries with multiple read and write operations.

well-it-wasnt-me commented 2 years ago

thank you so much

well-it-wasnt-me commented 2 years ago

Thank you so much !