Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

error handling in codeigniter

In my project to catch all the PHP errors I have set up my error handling mechanism as follows:

  1. I have set error_reporting() in index.php file which overrides anything in the php.ini file
  2. An error handler is set in system/codeigniter/CodeIgniter.php using set_error_handler - this error handler, _exception_handler, is found in system/codeigniter/Common.php
  3. The _exception_handler function ignores E_STRICT errors, calls the show_php_error function From the Exceptions system library if the severity is that specified by your error_reporting() function in index.php and logs the error according to whatever you have set up in your config.php file
  4. The handler returns FALSE so after this PHP goes on to handle the error however it normally would according your error_reporting level and display_errors setting.

The thing that is puzzling me is that E_ERROR errors i.e. fatal errors don’t seem to be being caught by _exception_handler at all. It’s not just that show_php_error isn’t being called, it looks like the function just isn’t being called for them. This is obviously a problem as it means that they aren’t get handled by show_php_error or logged. For example if I deliberately mistype $this->load->views('foo'); in a controller, the handler doesn’t get called.

Any suggestion about error handling would be much appreciated, thanks!

like image 509
troy Avatar asked Feb 08 '13 17:02

troy


1 Answers

Now this is a rather big debate: Whether you should catch the fatal errors or not. Some say that they are FATAL so you dont know in which condition is the system but I will go with the "try to do the cleanup if the error occured". In order to catch ALL fatal errors you will need to setup a pre_system hook. go to application/config/hooks.php and enter

$hook['pre_system'][] = array(
'class' => 'PHPFatalError',
'function' => 'setHandler',
'filename' => 'PHPFatalError.php',
'filepath' => 'hooks'
);

after that go to hooks directory and add your handling of the error:

<?php
    class PHPFatalError {

    public function setHandler() {
            register_shutdown_function('handleShutdown');
        }

    }

    function handleShutdown() {
        if (($error = error_get_last())) {
            ob_start();
                echo "<pre>";
            var_dump($error);
                echo "</pre>";
            $message = ob_get_clean();
            sendEmail($message);
            ob_start();
            echo '{"status":"error","message":"Internal application error!"}';
            ob_flush();
            exit();
        }
    }

as you can see we are using the register_shutdown_function to run a function that checks if an error had occured and if it had send it via email to the developer. This setup is working flawlessly for over 2 years in several CI projects that I have been working with.

like image 63
tix3 Avatar answered Oct 06 '22 06:10

tix3