Welcome Guest, Not a member yet? Register   Sign In
Catch Fatal Errors
#1

[eluser]dmorin[/eluser]
I'm curious if anyone has implemented something where fatal errors can be caught by codeigniter and have a nice page returned to the user instead of a blank page when display_errors is turned off.

There are many situations where a fatal error might be thrown on a production site. The most likely example for me is if the database is unreachable.
#2

[eluser]Chris Newton[/eluser]
I do have something like this set up. It's a library I made called error_sender, and basically it allows me to co-opt the standard error display to suit my own purposes. It requires that display_errors be turned on though. The message shown to the user is my message however, rather than the standard PHP message, and I've changed the standard template to use something a little more visually pleasing.

Code:
<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* Bn_error_sender
*
* sends errors, logs them, and shoes them to the user
*
* @package default
* @author  Chris Newton <[email protected]>
* @version 1.1
**/
class Bn_error_sender {
    /**
     * $CI
     *
     * this stores the CodeIgniter instance object
     *
     * @var Object
     **/
    var $CI;
    /**
     * $send_to
     *
     * Configure to: email address
     *
     * @var string
     **/
    var $send_to;
    /**
     * $send_from
     *
     * Configure from: email address
     *
     * @var string
     **/
    var $send_from;
    /**
     * Constructor
     *
     * @return void
     * @uses email library
     * @author Chris Newton
     **/
    function Bn_error_sender() {
        $this->CI =& get_instance();
        $this->send_to="[email protected]";
        $this->send_from="[email protected]"
        log_message('debug', 'Error Sender class initialized.');
        $this->CI->load->library('email');
    }
    /**
     * send
     *
     * @access public
     * @param string $subject
     * @param string $error (php error)
     * @param string $report_to_user the text to display on screen
     * @return void
     * @author Chris Newton
     **/
    public function send($subject="Error Report",$error,$report_to_user)
    {
        $this->CI->email->from($this->send_to, 'Error Reporter');
        $this->CI->email->to($this->send_from);
        $this->CI->email->subject($subject);
        $this->CI->email->message($error);
        $this->CI->email->send();
        log_message('error',$error);
        show_error($report_to_user);
    }
}

This doesn't catch fatal errors (most of which can't be caught) but at least let's me account for some pretty catastrophic errors that might occur, like the DB being unreachable, with error messaging provided to the user on what they should do.
#3

[eluser]dmorin[/eluser]
Thanks for replying with your error code. I did find a way to catch fatal errors. Basically, you have to modify your index.php script and change

Code:
require_once BASEPATH.'codeigniter/CodeIgniter'.EXT;
To
Code:
ob_start();

$res = register_shutdown_function('shutdown');

require_once BASEPATH.'codeigniter/CodeIgniter'.EXT;

function shutdown()
{
    if ($error = error_get_last()) {
        if (isset($error['type']) && ($error['type'] == E_ERROR || $error['type'] == E_PARSE || $error['type'] == E_COMPILE_ERROR)) {
            ob_end_clean();

            if (!headers_sent()) {
                header('HTTP/1.1 500 Internal Server Error');
            }

            echo '<h1>Bad Stuff Happened</h1>';
            echo '<p>But that is okay</p>';
            echo '<code>' . print_r($error, true) . '</code>';
        }
    }
}

ob_end_flush();

The code is from http://www.eggplant.ws/blog/php/mayday-php-going-down/. The idea is instead of printing out the Bad Stuff Happened and errors, I could return a decent looking page back to the browser that says "An unrecoverable error has occurred. Please use the back button to return to the previous page". It's certainly difficult though since we have no way of knowing what CI helpers/libraries are loaded and therefore need to do everything without them in a way that's virtually certain to never throw an error.

If anyone has comments on how to better implement this, or if you see an issue with the code above, let me know. I wasn't sure if adding in another lever of ob_buffers would mess with loading views, but it seems to work correctly.




Theme © iAndrew 2016 - Forum software by © MyBB