我正在使用 Codeigniter v4.4.5 并努力捕获 MySQL 重复条目异常。如果有任何重复的值,那么我想在我的控制器中处理,以便我可以将相关消息发送回用户。但是,当出现重复条目错误时,Codeigniter 会记录异常,但不会将该异常发送回控制器。我进一步调查,可以看到异常首先在 CodeIgniter\Database\MySQLi\Connection.php 中引发(代码如下)
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;
}
如果我有 DBDebug TRUE 那么它将异常传递给 CodeIgniter\Database\BaseConnection (下面的代码)
// Run the query for real
try {
$exception = null;
$this->resultID = $this->simpleQuery($query->getQuery());
} catch (DatabaseException $exception) {
$this->resultID = false;
}
但是它永远不会传回控制器。 我在控制器中有 try/catch ,如下所示,但它永远不会出现,因为框架代码永远不会传回异常。 大家有什么想法吗? 以下代码来自我的控制器。
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);
}
如果其他人正在寻找答案,那么您可以通过两种方式进行。
$this->db->transException(true)
。这样,如果存在 DB 异常,那么它将被 try catch 块中的 DatabaseException 捕获。我实际上正在检查数据库异常中的“重复错误”。<?php
// When DBDebug in the Database Config must be true.
use CodeIgniter\Database\Exceptions\DatabaseException;
try {
$this->db->transException(true)->transStart();
$this->db->query('AN SQL QUERY...');
$this->db->query('ANOTHER QUERY...');
$this->db->query('AND YET ANOTHER QUERY...');
$this->db->transComplete();
} catch (DatabaseException $e) {
// Automatically rolled back already.
// Check if the exception message or error code indicates a duplicate entry error
if (strpos($e->getMessage(), 'Duplicate entry') !== false || $e->getCode() === 1062) {
//return error message you want
} else {
//return error message you want
}
}
您可以在这里阅读更多信息 - https://codeigniter4.github.io/CodeIgniter4/database/transactions.html#throwing-exceptions