Codeigniter: Try Catch Is Not Working in Model Class

CodeIgniter: Try Catch is not working in model class

CI has no good support for exceptions. You DB queries will call some vague CI error_logging thingie called show_error(). What you need to do is setup proper exception handling.

Basically you can follow the entire recipe.

Now all your database errors will automatically throw exceptions. And as a bonus you have good exception handling in your entire CI application.

Register a custom errorhandler that transforms PHP errors into exceptions, for instance put this in top of your 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");

Register an uncaught exception handler, put something like this in your 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");

Set a termination handler:

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");

Set a custom assert handler that converts asserts into exceptions, put something like this in your 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 wrappers like this in your controllers

public function controller_method( )
{
try
{
// normal flow
}
catch( Exception $e )
{
log_message( 'error', $e->getMessage( ) . ' in ' . $e->getFile() . ':' . $e->getLine() );
// on error
}
}

You can tune and customize the whole thing to your likings!

Hope this helps.

You will also need to intercept the CI show_error method. Place this in 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 );
}
}

And leave in application/config/database.php this setting on FALSE to have database errors converted into exceptions.

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

CI has a few (very) weak points, such as exception-handling but this will go a long way correcting that.

If you are going to use transactions, make sure you do rollbacks on exceptions. Related to this NEVER (as in EVER) use persistant connections as open transactions and other session specific DB state will be picked up / continued by other sessions.

Codeigniter 3: Can't catch database error using try catch block

As for CI 3, below code gets database error code and error message. db_debug is set to FALSE.

public function add() {
try {
$this->db->trans_start(FALSE);
$this->db->insert('users', $preparedData);
$this->db->trans_complete();

// documentation at
// https://www.codeigniter.com/userguide3/database/queries.html#handling-errors
// says; "the error() method will return an array containing its code and message"
$db_error = $this->db->error();
if (!empty($db_error)) {
throw new Exception('Database error! Error Code [' . $db_error['code'] . '] Error: ' . $db_error['message']);
return false; // unreachable retrun statement !!!
}
return TRUE;
} catch (Exception $e) {
// this will not catch DB related errors. But it will include them, because this is more general.
log_message('error: ',$e->getMessage());
return;
}
}

Refer to documentation at https://www.codeigniter.com/userguide3/database/queries.html#handling-errors

saying

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

It is a bit incomplete in my opinion because it does not show error code and error message in the example code.

Codeigniter Try Catch Transaction

There are a several ways to do this. Perhaps the easiest is this.

Model:

//I'm making the function up cause you don't show it
public function do_something(){

//all code the same up to here...

if($nc > 0){
//Updates Count
$process = array('count' => $nc);

$this->db->where('table_id', $r);
$this->db->update('table1', $process);
} else {
$this->db->trans_rollback();
throw new Exception('Model whats_its_name has nothing to process');
}

The catch statement in the model will catch any exception that the database class(es) might throw. (Do they throw any exceptions? I don't know.)

Controller

try{
$this->some_model->do_something();
}
catch (Exception $e) {
//catch the exception thrown in do_something()
//additional handling here
}

All that said, it might be wise to check $_POST['count'] for the appropriate values before you call $this->some_model->do_something();

Custom way to log the exception in codeigniter

I followed this method and got the answer. https://stackoverflow.com/a/15860744/11367846

And added some customization for my requirement. In the controller page in exception catch added code for customized log.

public function controller_method( )
{
try
{
// normal flow
}
catch( Exception $e )
{
$trace = $e->getTrace();

$result = 'Exception: "';
$result .= $e->getMessage();
$result .= '" @ ';
if($trace[4]['file'] != '') {
$result .= ' File : '.$trace[4]['file'].'::: Line : '.$trace[4]['line'].' ::: Source :'.$trace[5]['class'].' -> '.$trace[5]['function'].' ::: Function : '.$trace[4]['class'].' -> '.$trace[4]['function'].' ::: Inputs :'.http_build_query($trace[4]['args']);
}

log_message( 'error', $result );
}

}

CodeIgniter - how to catch DB errors?

Use error() method:

$this->db->error(); 

For CodeIgniter 2, you can use the following functions which are now deprecated:

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

Database Error Handling problem in CodeIgniter

You need to throw an exception if there was some mysql error:

try {
$query_str = "SELECT * FROM tbl_user WHERE username = '".$username."'";
$result = $this->db->query($query_str);

if (!$result)
{
throw new Exception('error in query');
return false;
}

return $result;

} catch (Exception $e) {
return;
}


Related Topics



Leave a reply



Submit