CodeIgniter - how to catch DB errors?

帅比萌擦擦* 提交于 2020-08-20 11:12:09


Is there a way to make CI throw an exception when it encounters a DB error instead of displaying a message like:

A Database Error Occurred Error Number: 1054 Unknown column 'foo' in 'where clause' SELECT * FROM (FooBar) WHERE foo = '1'

NOTE: I only want this to happen in one controller. In the other controllers, I'm happy for it to display the DB error messages.


Try these CI functions

$this->db->_error_message(); (mysql_error equivalent)
$this->db->_error_number(); (mysql_errno equivalent)


Functions are deprecated, use error() instead:



Maybe this:

$db_debug = $this->db->db_debug; //save setting

$this->db->db_debug = FALSE; //disable debugging for queries

$result = $this->db->query($sql); //run query

//check for errors, etc

$this->db->db_debug = $db_debug; //restore setting


In Codeigniter 3.0 (CI3), all you have to do is $this->db->error()

If you need to get the last error that has occured, the error() method will return an array containing its code and message


You must turn debug off for database in config/database.php ->

$db['default']['db_debug'] = FALSE;

It is better for your website security.


I know this thread is old, but just in case there's someone else having this issue. This is a trick I used without touching the CI db classes. Leave your debug on and in your error view file, throw an exception.

So in you db config, you have :

$db['default']['db_debug'] = true;

Then in your db error view file, mine is in application/errors/error_db.php replace all content with the following:

$message = preg_replace('/(<\/?p>)+/', ' ', $message);
throw new Exception("Database error occured with message : {$message}");


Since the view file will be called, the error will always get thrown as an exception, you may later add different views for different environment.


I have created an simple library for that:

defined('BASEPATH') OR exit('No direct script access allowed');

class exceptions {

    public function checkForError() {
        $error = get_instance()->db->error();
        if ($error['code'])
            throw new MySQLException($error);

abstract class UserException extends Exception {
    public abstract function getUserMessage();

class MySQLException extends UserException {
    private $errorNumber;
    private $errorMessage;

    public function __construct(array $error) {
        $this->errorNumber = "Error Code(" . $error['code'] . ")";
        $this->errorMessage = $error['message'];

    public function getUserMessage() {
        return array(
            "error" => array (
                "code" => $this->errorNumber,
                "message" => $this->errorMessage


The example query:

function insertId($id){
    $data = array(
        'id' => $id,

    $this->db->insert('test', $data);
    return $this->db->insert_id();

And I can catch it this way in my controller:

 try {
 } catch (UserException $error){
     //do whatever you want when there is an mysql error



an example that worked for me:

$query = "some buggy sql statement";

$this->db->db_debug = false;

    $error = $this->db->error();
    // do something in error case
    // do something in success case



Put this code in a file called MY_Exceptions.php in application/core folder:


if (!defined('BASEPATH'))
    exit('No direct script access allowed');

 * Class dealing with errors as exceptions
class MY_Exceptions extends CI_Exceptions

     * Force exception throwing on erros
    public function show_error($heading, $message, $template = 'error_general', $status_code = 500)

        $message = implode(" / ", (!is_array($message)) ? array($message) : $message);

        throw new CiError($message);


 * Captured error from Code Igniter
class CiError extends Exception


It will make all the Code Igniter errors to be treated as Exception (CiError). Then, turn all your database debug on:

$db['default']['db_debug'] = true;


Use it


It is better for finding error.After completing your site. Close the error messages using it

    $db['default']['db_debug'] = FALSE;

You will change it in your config folder's database.php


Disable debugging of errors.

    $data_user = $this->getDataUser();
    $id_user   = $this->getId_user();

    $this->db->db_debug = false;
    $this->db->where(['id' => $id_user]);
    $res = $this->db->update(self::$table, $data_user['user']);

        $error = $this->db->error();
        return $error;
        //return array $error['code'] & $error['message']
        return 1;


If one uses PDO, additional to all the answers above.

I log my errors silently as below

        $q = $this->db->conn_id->prepare($query);

        if($q instanceof PDOStatement) {
           // go on with bind values and execute

        } else {

          $dbError = $this->db->error();
          $this->Logger_model->logError('Db Error', date('Y-m-d H:i:s'), __METHOD__.' Line '.__LINE__, 'Code: '.$dbError['code'].' -  '.'Message: '.$dbError['message']);



In sybase_driver.php

* Manejador de Mensajes de Error Sybase
* Autor: Isaí Moreno
* Fecha: 06/Nov/2019


public static function SetCodeErrorSybase($Code) {
    if ($Code != 3621) {  /*No se toma en cuenta el código de command aborted*/
        CI_DB_sybase_driver::$CODE_ERROR_SYBASE = trim(CI_DB_sybase_driver::$CODE_ERROR_SYBASE.' '.$Code);       

public static function GetCodeErrorSybase() {               
    return CI_DB_sybase_driver::$CODE_ERROR_SYBASE;

public static function msg_handler($msgnumber, $severity, $state, $line, $text)
    log_message('info', 'CI_DB_sybase_driver - CODE ERROR ['.$msgnumber.'] Mensaje - '.$text);

// ------------------------------------------------------------------------

Add and modify the following methods in the same sybase_driver.php file

 * The error message number
 * @access  private
 * @return  integer
function _error_number()
    // Are error numbers supported?
    return CI_DB_sybase_driver::GetCodeErrorSybase();

function _sybase_set_message_handler()
    // Are error numbers supported?     
    return sybase_set_message_handler('CI_DB_sybase_driver::msg_handler');

Implement in the function of a controller.

public function Eliminar_DUPLA(){       

        $this->db->_sybase_set_message_handler();  <<<<<------- Activar Manejador de errores de sybase

        if ($Dupla_Eliminada){
            MostrarNotificacion("Se eliminó DUPLA exitosamente","OK",true);
            $Error = $this->db->_error_number();  <<<<----- Obtengo el código de error de sybase para personilzar mensaje al usuario    
            MostrarNotificacion("Ocurrio un error al intentar eliminar Dupla","Error",true);
            if ($Error == 547) {
                MostrarNotificacion("<strong>Código de error :[".$Error.']. No se puede eliminar documento Padre.</strong>',"Error",true);
            }  else {                   
                MostrarNotificacion("<strong>Código de Error :[".$Error.']</strong><br>',"Error",true);                 

        echo "@".Obtener_Contador_Notificaciones();
        if ($Operacion_Borrado_Exitosa){
            echo "@T";
            echo "@F";


In the log you can check the codes and messages sent by the database server.

INFO - 2019-11-06 19:26:33 -> CI_DB_sybase_driver - CODE ERROR [547] Message - Dependent foreign key constraint violation in a referential integrity constraint. dbname = 'database', table name = 'mitabla', constraint name = 'FK_SR_RELAC_REFERENCE_SR_mitabla'. INFO - 2019-11-06 19:26:33 -> CI_DB_sybase_driver - CODE ERROR [3621] Message - Command has been aborted. ERROR - 2019-11-06 19:26:33 -> Query error: - Invalid query: delete from mitabla where ID = 1019.