CodeIgniter Forums
Catch database exception - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: CodeIgniter 4 (https://forum.codeigniter.com/forumdisplay.php?fid=28)
+--- Forum: CodeIgniter 4 Support (https://forum.codeigniter.com/forumdisplay.php?fid=30)
+--- Thread: Catch database exception (/showthread.php?tid=77740)



Catch database exception - Michal_PB1 - 10-13-2020

Hi,

I have some problems with catching a database exception. On the development, everything works as I expected but not on the production.

My code looks like below:

PHP Code:
        try {

            $orderStatus = new OrderStatus;

            $orderStatus->insert(new OrderStatusEntity([
                'order_id' => $orderId,
                'status_id' => $statusId
            
]));

        }
        catch (\mysqli_sql_exception $e) {

            if ($e->getCode() === 1062)
            {
                log_message('warning''Duplicate status ({status}) for order {id}', [
                    'status' => $statusId,
                    'id' => $orderId
                
]);
            }

        

On the development environment in the logs file, I have only `Duplicate status...` - as I want

On the production environment in the logs file, I have a raw exception

PHP Code:
ERROR 2020-10-13 20:25:22 --> mysqli_sql_exceptionDuplicate entry '441-2' for key 'order_id_status_id' in /var/www/mrsystem/vendor/codeigniter4/framework/system/Database/MySQLi/Connection.php:331
Stack trace
:
#0 /var/www/mrsystem/vendor/codeigniter4/framework/system/Database/MySQLi/Connection.php(331): mysqli->query('INSERT INTO `or...')
#1 /var/www/mrsystem/vendor/codeigniter4/framework/system/Database/BaseConnection.php(741): CodeIgniter\Database\MySQLi\Connection->execute('INSERT INTO `or...')
#2 /var/www/mrsystem/vendor/codeigniter4/framework/system/Database/BaseConnection.php(669): CodeIgniter\Database\BaseConnection->simpleQuery('INSERT INTO `or...')
#3 /var/www/mrsystem/vendor/codeigniter4/framework/system/Database/BaseBuilder.php(2249): CodeIgniter\Database\BaseConnection->query('INSERT INTO `or...', Array, false)
#4 /var/www/mrsystem/vendor/codeigniter4/framework/system/Model.php(755): CodeIgniter\Database\BaseBuilder->insert()
#5 /var/www/mrsystem/bundles/Ecommerce/Order/Order.php(272): CodeIgniter\Model->insert(Array) 

If I changed in the Database config variable DBDebug to TRUE then I have a raw exception and logged a warning

PHP Code:
ERROR 2020-10-13 20:25:22 --> mysqli_sql_exceptionDuplicate entry '441-2' for key 'order_id_status_id' in /var/www/mrsystem/vendor/codeigniter4/framework/system/Database/MySQLi/Connection.php:331
Stack trace
:
#0 /var/www/mrsystem/vendor/codeigniter4/framework/system/Database/MySQLi/Connection.php(331): mysqli->query('INSERT INTO `or...')
#1 /var/www/mrsystem/vendor/codeigniter4/framework/system/Database/BaseConnection.php(741): CodeIgniter\Database\MySQLi\Connection->execute('INSERT INTO `or...')
#2 /var/www/mrsystem/vendor/codeigniter4/framework/system/Database/BaseConnection.php(669): CodeIgniter\Database\BaseConnection->simpleQuery('INSERT INTO `or...')
#3 /var/www/mrsystem/vendor/codeigniter4/framework/system/Database/BaseBuilder.php(2249): CodeIgniter\Database\BaseConnection->query('INSERT INTO `or...', Array, false)
#4 /var/www/mrsystem/vendor/codeigniter4/framework/system/Model.php(755): CodeIgniter\Database\BaseBuilder->insert()
#5 /var/www/mrsystem/bundles/Ecommerce/Order/Order.php(272): CodeIgniter\Model->insert(Array)
(...)

WARNING 2020-10-13 20:38:20 --> Duplicate status (2) for order 441 

Can someone tell me what I am doing wrong? How to on the production environment get an only logged warning?


RE: Catch database exception - InsiteFX - 10-13-2020

You can try it using CodeIgniters Exceptions.

PHP Code:
try
{
    $orderStatus = new OrderStatus;

    $orderStatus->insert(new OrderStatusEntity([
        'order_id'  => $orderId,
        'status_id' => $statusId
    
]));
}
catch (\
Exception $e)
{
    if ($e->getCode() === 1062)
    {
        log_message('warning''Duplicate status ({status}) for order {id}', [
            'status' => $statusId,
            'id'     => $orderId
        
]);
    }

    exit($e->getMessage());




RE: Catch database exception - Michal_PB1 - 10-14-2020

Unfortunately, what you propose doesn't help :/

EDIT:

I cannot use `exit($e->getMessage());` because the executed code is stopped


RE: Catch database exception - InsiteFX - 10-14-2020

I was surfing the web and came across this maybe it will help you out.

Code:
How to use try catch with MySQL
The PHP libraries for MySQL, PDO, and mysqli, have different modes for error handling.
If you do not have exceptions enables for those libraries, you can’t use try catch blocks.
This makes error handling different and perhaps more complicated.

PDO
In PDO, you must enable ERRMODE_EXCEPTION when creating the connection.

// connect to MySQL
$conn = new PDO('mysql:host=localhost;dbname=stackifydb;charset=utf8mb4', 'username', 'password');

//PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Learn more about PDO attributes from the PHP docs.

MySQL
For mysqli, you must do something similar:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

Learn more from the MySQL docs.

This may help others out also.

After looking at the MySQLi connection it is not setting these up in CodeIgniter.


RE: Catch database exception - Michal_PB1 - 11-30-2020

I found in system/Database/MySQLi/Connection.php:329 this code:

PHP Code:
        try
        {
            return 
$this->connID->query($this->prepQuery($sql));
        }
        catch (\
mysqli_sql_exception $e)
        {
            
log_message('error'$e);
            if (
$this->DBDebug)
            {
                throw 
$e;
            }
        } 

Maybe I'm wrong but, if we have DBDebug sets true then we shouldn't call log_message? So I mean that log_message should be inside else. What do you think?


RE: Catch database exception - InsiteFX - 11-30-2020

No, because it needs to log the message before it invokes the exception error.


RE: Catch database exception - Michal_PB1 - 11-30-2020

But what is a sens to log an error if we have enabled database throws for debug mode? In this situation, every time an error is logged even if we catch it manually and do something.