From e48be5ef7c6b73e51ab297c55950180261b6c061 Mon Sep 17 00:00:00 2001 From: Florian Pritz Date: Thu, 18 Sep 2014 17:07:41 +0200 Subject: Improve handling of PHP errors This converts any error (including INFO, NOTICE and those hidden with @) to an exception and displays a nice error page for uncaught exceptions. Signed-off-by: Florian Pritz --- application/errors/error_general.php | 5 +++- index.php | 55 ++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/application/errors/error_general.php b/application/errors/error_general.php index be495e4f6..844dfb74d 100644 --- a/application/errors/error_general.php +++ b/application/errors/error_general.php @@ -43,6 +43,9 @@ if (class_exists("CI_Controller") && !isset($GLOBALS["is_error_page"])) { ", "\n", $message); } else { // default CI error page ?> @@ -96,7 +99,7 @@ code { -webkit-box-shadow: 0 0 8px #D0D0D0; } -p { +p, div { margin: 12px 15px 12px 15px; } diff --git a/index.php b/index.php index 2bf26537b..00ab370c3 100644 --- a/index.php +++ b/index.php @@ -195,6 +195,61 @@ if (false && defined('ENVIRONMENT')) putenv('HOME='.FCPATH); } +/* + * Custom error handling + */ +/* CI uses that name for it's error handling function. It misleading, but + * whatever. If I don't use it the framework will override my handler later. + */ +function _exception_handler($errno, $errstr, $errfile, $errline) +{ + if (!(error_reporting() & $errno)) { + // This error code is not included in error_reporting + return; + } + throw new ErrorException($errstr, 0, $errno, $errfile, $errline); +} +set_error_handler("_exception_handler"); + +// The actual exception handler +function _actual_exception_handler($e) +{ + $display_errors = in_array(strtolower(ini_get('display_errors')), array('1', 'on', 'true', 'stdout')); + + $GLOBALS["is_error_page"] = true; + $heading = "Internal Server Error"; + $message = "

An unhandled error occured.

\n"; + if ($display_errors) { + $message .= '
'; + $message .= 'Fatal error: Uncaught exception '.get_class($e).'
'; + $message .= 'Message: '.$e->getMessage().'
'; + $message .= '
'.(str_replace(FCPATH, "./", $e->getTraceAsString())).'
'; + $message .= 'thrown in '.$e->getFile().' on line '.$e->getLine().'
'; + $message .= '
'; + } else { + $message .="

More information can be found in syslog or by enabling display_errors.

"; + } + + error_log($e); + + $message = "$message"; + include APPPATH."/errors/error_general.php"; +} +set_exception_handler('_actual_exception_handler'); + +/** + * Checks for a fatal error, work around for set_error_handler not working on fatal errors. + */ +function check_for_fatal() +{ + $error = error_get_last(); + if ($error["type"] == E_ERROR) { + _actual_exception_handler(new ErrorException( + $error["message"], 0, $error["type"], $error["file"], $error["line"])); + } +} +register_shutdown_function("check_for_fatal"); + /* * -------------------------------------------------------------------- * LOAD THE BOOTSTRAP FILE -- cgit v1.2.3-24-g4f1b