Unified error handlers. Now the regular error handler will receive the fatal errors too.

This commit is contained in:
Juan Basso 2012-04-01 23:49:40 -04:00
parent a72288c378
commit 9beaa9602f
5 changed files with 19 additions and 24 deletions

View file

@ -41,8 +41,6 @@
* *
* Options: * Options:
* *
* - `fatalErrorHandler` - callback - The callback to handle fatal errors. You can set this to any
* callable type, including anonymous functions. Setting it to false will disable the feature.
* - `handler` - callback - The callback to handle errors. You can set this to any callable type, * - `handler` - callback - The callback to handle errors. You can set this to any callable type,
* including anonymous functions. * including anonymous functions.
* - `level` - int - The level of errors you are interested in capturing. * - `level` - int - The level of errors you are interested in capturing.
@ -51,7 +49,6 @@
* @see ErrorHandler for more information on error handling and configuration. * @see ErrorHandler for more information on error handling and configuration.
*/ */
Configure::write('Error', array( Configure::write('Error', array(
'fatalErrorHandler' => 'ErrorHandler::handleFatalError',
'handler' => 'ErrorHandler::handleError', 'handler' => 'ErrorHandler::handleError',
'level' => E_ALL & ~E_DEPRECATED, 'level' => E_ALL & ~E_DEPRECATED,
'trace' => true 'trace' => true

View file

@ -41,8 +41,6 @@
* *
* Options: * Options:
* *
* - `fatalErrorHandler` - callback - The callback to handle fatal errors. You can set this to any
* callable type, including anonymous functions. Setting it to false will disable the feature.
* - `handler` - callback - The callback to handle errors. You can set this to any callable type, * - `handler` - callback - The callback to handle errors. You can set this to any callable type,
* including anonymous functions. * including anonymous functions.
* - `level` - int - The level of errors you are interested in capturing. * - `level` - int - The level of errors you are interested in capturing.
@ -51,7 +49,6 @@
* @see ErrorHandler for more information on error handling and configuration. * @see ErrorHandler for more information on error handling and configuration.
*/ */
Configure::write('Error', array( Configure::write('Error', array(
'fatalErrorHandler' => 'ErrorHandler::handleFatalError',
'handler' => 'ErrorHandler::handleError', 'handler' => 'ErrorHandler::handleError',
'level' => E_ALL & ~E_DEPRECATED, 'level' => E_ALL & ~E_DEPRECATED,
'trace' => true 'trace' => true

View file

@ -913,14 +913,11 @@ class App {
return; return;
} }
$fatalErrorHandler = Configure::read('Error.fatalErrorHandler'); $errorHandler = Configure::read('Error.handler');
if ($fatalErrorHandler === null) { if (!is_callable($errorHandler)) {
$fatalErrorHandler = 'ErrorHandler::handleFatalError';
}
if (!is_callable($fatalErrorHandler)) {
return; return;
} }
call_user_func($fatalErrorHandler, $lastError); call_user_func($errorHandler, $lastError['type'], $lastError['message'], $lastError['file'], $lastError['line'], array());
} }
} }

View file

@ -158,6 +158,9 @@ class ErrorHandler {
} }
$errorConfig = Configure::read('Error'); $errorConfig = Configure::read('Error');
list($error, $log) = self::mapErrorCode($code); list($error, $log) = self::mapErrorCode($code);
if ($log === LOG_ERROR) {
return self::handleFatalError($code, $description, $file, $line);
}
$debug = Configure::read('debug'); $debug = Configure::read('debug');
if ($debug) { if ($debug) {
@ -186,24 +189,28 @@ class ErrorHandler {
/** /**
* Generate an error page when some fatal error happens. * Generate an error page when some fatal error happens.
* *
* @param array $error Array with error information. See `error_get_last()` function * @param integer $code Code of error
* @return void * @param string $description Error description
* @param string $file File on which error occurred
* @param integer $line Line that triggered the error
* @return boolean
*/ */
public static function handleFatalError($error) { public static function handleFatalError($code, $description, $file, $line) {
$logMessage = 'Fatal Error (' . $error['type'] . '): ' . $error['message'] . ' in [' . $error['file'] . ', line ' . $error['line'] . ']'; $logMessage = 'Fatal Error (' . $code . '): ' . $description . ' in [' . $file . ', line ' . $line . ']';
CakeLog::write(LOG_ERROR, $logMessage); CakeLog::write(LOG_ERROR, $logMessage);
$exceptionHandler = Configure::read('Exception.handler'); $exceptionHandler = Configure::read('Exception.handler');
if (!is_callable($exceptionHandler)) { if (!is_callable($exceptionHandler)) {
return; return false;
} }
ob_clean(); ob_clean();
if (Configure::read('debug')) { if (Configure::read('debug')) {
call_user_func($exceptionHandler, new FatalErrorException($error['message'], 500, $error['file'], $error['line'])); call_user_func($exceptionHandler, new FatalErrorException($description, 500, $file, $line));
} else { } else {
call_user_func($exceptionHandler, new InternalErrorException()); call_user_func($exceptionHandler, new InternalErrorException());
} }
return false;
} }
/** /**

View file

@ -89,7 +89,6 @@ class ErrorHandlerTest extends CakeTestCase {
return array( return array(
array(E_USER_NOTICE, 'Notice'), array(E_USER_NOTICE, 'Notice'),
array(E_USER_WARNING, 'Warning'), array(E_USER_WARNING, 'Warning'),
array(E_USER_ERROR, 'Fatal Error'),
); );
} }
@ -248,11 +247,10 @@ class ErrorHandlerTest extends CakeTestCase {
$originalDebugLevel = Configure::read('debug'); $originalDebugLevel = Configure::read('debug');
$line = __LINE__; $line = __LINE__;
$error = array('type' => E_ERROR, 'message' => 'Something wrong', 'file' => __FILE__, 'line' => $line);
ob_start(); ob_start();
Configure::write('debug', 1); Configure::write('debug', 1);
ErrorHandler::handleFatalError($error); ErrorHandler::handleFatalError(E_ERROR, 'Something wrong', __FILE__, $line);
$result = ob_get_clean(); $result = ob_get_clean();
$this->assertContains('Something wrong', $result, 'message missing.'); $this->assertContains('Something wrong', $result, 'message missing.');
$this->assertContains(__FILE__, $result, 'filename missing.'); $this->assertContains(__FILE__, $result, 'filename missing.');
@ -260,7 +258,7 @@ class ErrorHandlerTest extends CakeTestCase {
ob_start(); ob_start();
Configure::write('debug', 0); Configure::write('debug', 0);
ErrorHandler::handleFatalError($error); ErrorHandler::handleFatalError(E_ERROR, 'Something wrong', __FILE__, $line);
$result = ob_get_clean(); $result = ob_get_clean();
$this->assertNotContains('Something wrong', $result, 'message must not appear.'); $this->assertNotContains('Something wrong', $result, 'message must not appear.');
$this->assertNotContains(__FILE__, $result, 'filename must not appear.'); $this->assertNotContains(__FILE__, $result, 'filename must not appear.');
@ -280,10 +278,9 @@ class ErrorHandlerTest extends CakeTestCase {
if (file_exists(LOGS . 'error.log')) { if (file_exists(LOGS . 'error.log')) {
unlink(LOGS . 'error.log'); unlink(LOGS . 'error.log');
} }
$error = array('type' => E_ERROR, 'message' => 'Something wrong', 'file' => __FILE__, 'line' => __LINE__);
ob_start(); ob_start();
ErrorHandler::handleFatalError($error); ErrorHandler::handleFatalError(E_ERROR, 'Something wrong', __FILE__, __LINE__);
ob_clean(); ob_clean();
$log = file(LOGS . 'error.log'); $log = file(LOGS . 'error.log');