I am using Codeigniter v4.4.5 and struggling to catch MySQL Duplicate entry exception. If there is any duplicate value then I want to handle in my controller so that I can send relevant message back to user. But when there is Duplicate Entry error, then Codeigniter is logging the exception but never send that exception back to Controller. I investigated further and can see that exception is first raised in CodeIgniter\Database\MySQLi\Connection.php (code below)
protected function execute(string $sql)
{
while ($this->connID->more_results()) {
$this->connID->next_result();
if ($res = $this->connID->store_result()) {
$res->free();
}
}
try {
return $this->connID->query($this->prepQuery($sql), $this->resultMode);
} catch (mysqli_sql_exception $e) {
log_message('error', (string) $e);
if ($this->DBDebug) {
throw new DatabaseException($e->getMessage(), $e->getCode(), $e);
}
}
return false;
}
If i have DBDebug TRUE then it passes the exception to CodeIgniter\Database\BaseConnection (code below)
// Run the query for real
try {
$exception = null;
$this->resultID = $this->simpleQuery($query->getQuery());
} catch (DatabaseException $exception) {
$this->resultID = false;
}
But then it never passes back to Controller. I have try/catch in controller as below, but it never comes to it, because framework code never passes exception back. Any idea guys. Below code from my controller.
try{
//...More code above
$modelProducts = new ProductsModel();
$modelProducts->insert($data_product);
//..EXCEPTION IS LOGGED HERE IN LOGS AS INSERTED VALUE IS DUPLICATED
//FURTHER CODE KEEPS getting progressed.
}
catch(DatabaseException $e)
{
**// THIS NEVER GET CALLED, EVEN THOUGH THERE WAS MYSQL EXCEPTION LOGGED IN LOGS**
log_message('error', __NAMESPACE__ . " > " . __FUNCTION__ . $e);
}
catch(Exception $e) {
**// THIS NEVER GET CALLED, EVEN THOUGH THERE WAS MYSQL EXCEPTION LOGGED IN LOGS**
log_message('error', __NAMESPACE__ . " > " . __FUNCTION__ . $e);
}
In case anyone else looking for answer, then you can do it 2 ways.
$this->db->transException(true). This way if there is DB exception then it will get caught by DatabaseException in try catch block. I am actually checking "Duplicate Error" in Database exception.You can read more here - https://codeigniter4.github.io/CodeIgniter4/database/transactions.html#throwing-exceptions