Solución:
CI no tiene un buen soporte para excepciones. Sus consultas de base de datos llamarán a alguna cosa vaga de registro de errores de CI llamada show_error (). Lo que debe hacer es configurar el manejo adecuado de excepciones.
Básicamente puedes seguir toda la receta.
Ahora todos los errores de su base de datos arrojarán excepciones automáticamente. Y como beneficio adicional, tiene un buen manejo de excepciones en toda su aplicación de CI.
Registre un controlador de errores personalizado que transforme los errores de PHP en excepciones, por ejemplo, coloque esto en la parte superior de su config / config.php
function my_error_handler($errno, $errstr, $errfile, $errline)
{
if (!(error_reporting() & $errno))
{
// This error code is not included in error_reporting
return;
}
log_message('error', "$errstr @$errfile::$errline($errno)" );
throw new ErrorException( $errstr, $errno, 0, $errfile, $errline );
}
set_error_handler("my_error_handler");
Registre un controlador de excepciones no detectado, coloque algo como esto en su config / config.php
function my_exception_handler($exception)
{
echo '<pre>';
print_r($exception);
echo '</pre>';
header( "HTTP/1.0 500 Internal Server Error" );
}
set_exception_handler("my_exception_handler");
Establecer un controlador de terminación:
function my_fatal_handler()
{
$errfile = "unknown file";
$errstr = "Fatal error";
$errno = E_CORE_ERROR;
$errline = 0;
$error = error_get_last();
if ( $error !== NULL )
{
echo '<pre>';
print_r($error);
echo '</pre>';
header( "HTTP/1.0 500 Internal Server Error" );
}
}
register_shutdown_function("my_fatal_handler");
Establezca un controlador de aserciones personalizado que convierta las afirmaciones en excepciones, coloque algo como esto en su config / config.php:
function my_assert_handler($file, $line, $code)
{
log_message('debug', "assertion failed @$file::$line($code)" );
throw new Exception( "assertion failed @$file::$line($code)" );
}
assert_options(ASSERT_ACTIVE, 1);
assert_options(ASSERT_WARNING, 0);
assert_options(ASSERT_BAIL, 0);
assert_options(ASSERT_QUIET_EVAL, 0);
assert_options(ASSERT_CALLBACK, 'my_assert_handler');
Use envoltorios como este en sus controladores
public function controller_method( )
{
try
{
// normal flow
}
catch( Exception $e )
{
log_message( 'error', $e->getMessage( ) . ' in ' . $e->getFile() . ':' . $e->getLine() );
// on error
}
}
¡Puedes ajustar y personalizar todo a tu gusto!
Espero que esto ayude.
También deberá interceptar el método show_error de CI. Coloque esto en application / core / MY_exceptions.php:
class MY_Exceptions extends CI_Exceptions
{
function show_error($heading, $message, $template="error_general", $status_code = 500)
{
log_message( 'debug', print_r( $message, TRUE ) );
throw new Exception(is_array($message) ? $message[1] : $message, $status_code );
}
}
Y deje en application / config / database.php esta configuración en FALSE para que los errores de la base de datos se conviertan en excepciones.
$db['default']['db_debug'] = TRUE;
CI tiene algunos puntos (muy) débiles, como el manejo de excepciones, pero esto contribuirá en gran medida a corregirlo.
Si va a utilizar transacciones, asegúrese de realizar reversiones en las excepciones. En relación con esto, NUNCA (como en NUNCA) use conexiones persistentes, ya que las transacciones abiertas y el estado de la base de datos específico de la sesión será recogido / continuado por otras sesiones.