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
How to Select All Column Name from a Table in Laravel
How to Set an Arrays Internal Pointer to a Specific Position? PHP/Xml
What Are the Valid Characters in PHP Variable, Method, Class, etc Names
Algorithm to Get All Possible String Combinations from Array Up to Certain Length
How to Cast Array Elements to Strings in PHP
"Adaptive Server Is Unavailable or Does Not Exist" Error Connecting to SQL Server from PHP
Non-Breaking Utf-8 0Xc2A0 Space and Preg_Replace Strange Behaviour
Unit Test Laravel's Formrequest
Laravel 5 Hasmany Relationship on Two Columns
How to Run Laravel Without Artisan
Getting Started with PHP Extension-Development
Special Characters in Fpdf with PHP
Search and Replace Multiple Values with Multiple/Different Values in PHP5