diff --git a/app/Config/core.php b/app/Config/core.php index 1c1283133..a36970f16 100644 --- a/app/Config/core.php +++ b/app/Config/core.php @@ -41,20 +41,20 @@ * * Options: * + * - `handleFatalError` - callback - The callback to handle fatal errors. You can set this to any + * callback type, including anonymous functions. * - `handler` - callback - The callback to handle errors. You can set this to any callback type, * including anonymous functions. * - `level` - int - The level of errors you are interested in capturing. * - `trace` - boolean - Include stack traces for errors in log files. - * - `handleFatalError` - boolean - Enable the CakePHP fatal error handler, generating custom - * pages for fatal errors instead of show broke pages. * * @see ErrorHandler for more information on error handling and configuration. */ Configure::write('Error', array( + 'handleFatalError' => 'ErrorHandler::handleFatalError', 'handler' => 'ErrorHandler::handleError', 'level' => E_ALL & ~E_DEPRECATED, - 'trace' => true, - 'handleFatalError' => true + 'trace' => true )); /** diff --git a/lib/Cake/Console/Templates/skel/Config/core.php b/lib/Cake/Console/Templates/skel/Config/core.php index 20c354bc9..cf22ed415 100644 --- a/lib/Cake/Console/Templates/skel/Config/core.php +++ b/lib/Cake/Console/Templates/skel/Config/core.php @@ -41,6 +41,8 @@ * * Options: * + * - `handleFatalError` - callback - The callback to handle fatal errors. You can set this to any + * callback type, including anonymous functions. * - `handler` - callback - The callback to handle errors. You can set this to any callback type, * including anonymous functions. * - `level` - int - The level of errors you are interested in capturing. @@ -49,6 +51,7 @@ * @see ErrorHandler for more information on error handling and configuration. */ Configure::write('Error', array( + 'handleFatalError' => 'ErrorHandler::handleFatalError', 'handler' => 'ErrorHandler::handleError', 'level' => E_ALL & ~E_DEPRECATED, 'trace' => true diff --git a/lib/Cake/Core/App.php b/lib/Cake/Core/App.php index e0817462a..fcc495b18 100644 --- a/lib/Cake/Core/App.php +++ b/lib/Cake/Core/App.php @@ -881,7 +881,8 @@ class App { /** * Object destructor. * - * Writes cache file if changes have been made to the $_map + * Writes cache file if changes have been made to the $_map. Also, check if a fatal + * error happened and call the handler. * * @return void */ @@ -892,6 +893,31 @@ class App { if (self::$_objectCacheChange) { Cache::write('object_map', self::$_objects, '_cake_core_'); } + + self::_checkFatalError(); + } + +/** + * Check if a fatal error happened and trigger the configured handler if configured + * + * @return void + */ + protected static function _checkFatalError() { + $lastError = error_get_last(); + if (!is_array($lastError)) { + return; + } + + list(, $log) = ErrorHandler::mapErrorCode($lastError['type']); + if ($log !== LOG_ERROR) { + return; + } + + $fatalErrorHandler = Configure::read('Error.handleFatalError'); + if (!is_callable($fatalErrorHandler)) { + return; + } + call_user_func($fatalErrorHandler, $lastError); } } diff --git a/lib/Cake/Core/Configure.php b/lib/Cake/Core/Configure.php index 4340588f0..9d47dd759 100644 --- a/lib/Cake/Core/Configure.php +++ b/lib/Cake/Core/Configure.php @@ -345,6 +345,5 @@ class Configure { if (!empty($exception['handler'])) { set_exception_handler($exception['handler']); } - register_shutdown_function('ErrorHandler::handleFatalError'); } } diff --git a/lib/Cake/Error/ErrorHandler.php b/lib/Cake/Error/ErrorHandler.php index 79e948e21..8a05b6e2c 100644 --- a/lib/Cake/Error/ErrorHandler.php +++ b/lib/Cake/Error/ErrorHandler.php @@ -186,27 +186,12 @@ class ErrorHandler { /** * Generate an error page when some fatal error happens. * - * Use Configure::write('Error.handleFatalError', false) to disable this feature - * + * @param array $error Array with error information. See `error_get_last()` function * @return void */ - public static function handleFatalError() { - if (Configure::read('Error.handleFatalError') !== true) { - return; - } - - $lastError = error_get_last(); - if (!is_array($lastError)) { - return; - } - - list($error, $log) = self::mapErrorCode($lastError['type']); - if ($log !== LOG_ERROR) { - return; - } - - $logMessage = $error . ' (' . $lastError['type'] . '): ' . $lastError['message'] . ' in [' . $lastError['file'] . ', line ' . $lastError['line'] . ']'; - CakeLog::write($log, $logMessage); + public static function handleFatalError($error) { + $logMessage = 'Fatal Error (' . $error['type'] . '): ' . $error['message'] . ' in [' . $error['file'] . ', line ' . $error['line'] . ']'; + CakeLog::write(LOG_ERROR, $logMessage); $exceptionHandler = Configure::read('Exception.handler'); if (!is_callable($exceptionHandler)) { @@ -215,7 +200,7 @@ class ErrorHandler { ob_clean(); if (Configure::read('debug')) { - call_user_func($exceptionHandler, new FatalErrorException($lastError['message'], 500, $lastError['file'], $lastError['line'])); + call_user_func($exceptionHandler, new FatalErrorException($error['message'], 500, $error['file'], $error['line'])); } else { call_user_func($exceptionHandler, new InternalErrorException()); }