Exceptions handler for Codeigniter

While developing web applications I use php exceptions model for handling errors, which is similar to ones used in java and other objective languages. When an error occurs you can throw an exception, then an Exception object is created. Exception can then be caught somewhere else in the code, where you can decide what to do in case of a particular error, here an exception object can be used to read details about the error. You can also create your own Exception class, or use one of the existing e.g. in SPL (see http://www.php.net/manual/en/spl.exceptions.php). This helps you recognize which kind of error occured, not just if (you can throw many exceptions in one function), and write many variants of application behaviour for different kinds of errors (exceptions thrown). Everything is explained in php manual (http://php.net/exceptions), read for details.

My problem was that very often my exception was caught just to be passed to the error class (then write to log file, print on screen etc.). I didn’t like repeating try/catch section of the code looking like this:

try {
  // code throwing exception(s)
} catch (Exception $exc) {
  new Error($exc);
}

In the above example Error class construct should be considered as an exception handler.

Built-in php (obviously 5, I believe nobody uses php 4 nowadays) set_exception_handler function comes of help. It lets you define a handler function used if an exception is not caught within a try/catch block. Presented ExceptionHandler class is a Codeigniter library, it should be auto loaded so handle function is always set as default handler (in constructor). Handle must be public, otherwise set_exception_handler won’t work. Class also contains functions for printing and logging exceptions details (you can add whatever you want to happen when your system is in trouble). You can obviously use it for handling exceptions in try/catch blocks, but it’s not necessary. Once library’s loaded, it’s object is already created under $this->librarynamenocapitals, so ‘manual’ run looks like this:

try {
  // code throwing exception(s)
} catch (Exception $exc) {
  $this->exceptionhandler->handle($exc);
}

You can also add other behaviours to this class such as: send email to admin, or return just particular answer code (nice in REST web services). You can change this depending on ENVIRONMENT constant mode (set in index.php, you should know this before writing anything in Codeigniter).

class ExceptionHandler {

    protected $oException;

    public function __construct() {
        // set default uncaught exceptions handler
        set_exception_handler(array($this, 'handle'));
    }

    /**
     * Handles exception regarding ENVIRONMENT constant
     * @param Exception $oException
     */
    public function handle(Exception $oException) {
        $this->oException = $oException;

        switch (ENVIRONMENT) {
            case 'development':
            case 'testing':
                $this->printException();
                $this->logException();
                break;
            case 'production':
                $this->logException();
                break;
        }
    }

    /**
     * Prints readable exception content to the browser
     */
    private function printException() {
        print("
");
        print("Code: " . $this->oException->getCode() . "
");
        print("Message: " . $this->oException->getMessage() . "
");
        print("File: " . $this->oException->getFile() . "
");
        print("Line: " . $this->oException->getLine() . "
");
        print("Trace: " . $this->oException->getTraceAsString() . "
");
        print("
");
 }

 /**
 * Logs exception in application/logs
 * Requires $config['log_threshold'] to be >= 1 (application/config/config.php)
 */
 private function logException() {
 log_message('error', $this->oException->getMessage()
 . ' ' . $this->oException->getCode()
 . ' ' . $this->oException->getFile()
 . ' ' . $this->oException->getLine()
 . "\n" . $this->oException->getTraceAsString());
 }

}

Please read this article if you want to extend provided class by handling also regular PHP errors.

Leave a Reply

Your email address will not be published. Required fields are marked *