From 6bf9363217137b6deb1dccb44ecc7d93875d49a3 Mon Sep 17 00:00:00 2001 From: Ceeram Date: Mon, 18 Mar 2013 16:16:03 +0100 Subject: [PATCH] Add option to skip exception types for logging. add blacklisting for logging exceptions add test for skipping exception logging, and fix typo and cs add example to docblock in core.php for skipLog remove app_error.php skips, those are no longer used in 2.x use assertContains instead of assertRegExp check for instanceof, instead of matching names --- app/Config/core.php | 3 ++ .../Console/Templates/skel/Config/core.php | 3 ++ lib/Cake/Error/ErrorHandler.php | 27 ++++++++++-- lib/Cake/Test/Case/Error/ErrorHandlerTest.php | 41 ++++++++++++++----- 4 files changed, 61 insertions(+), 13 deletions(-) diff --git a/app/Config/core.php b/app/Config/core.php index c705ece8a..44271a6a9 100644 --- a/app/Config/core.php +++ b/app/Config/core.php @@ -70,6 +70,9 @@ * - `renderer` - string - The class responsible for rendering uncaught exceptions. If you choose a custom class you * should place the file for that class in app/Lib/Error. This class needs to implement a render method. * - `log` - boolean - Should Exceptions be logged? + * - `skipLog` - array - list of exceptions to skip for logging. Exceptions that + * extend one of the listed exceptions will also be skipped for logging. + * Example: `'skipLog' => array('NotFoundException', 'UnauthorizedException')` * * @see ErrorHandler for more information on exception handling and configuration. */ diff --git a/lib/Cake/Console/Templates/skel/Config/core.php b/lib/Cake/Console/Templates/skel/Config/core.php index c705ece8a..c3e5efa6b 100644 --- a/lib/Cake/Console/Templates/skel/Config/core.php +++ b/lib/Cake/Console/Templates/skel/Config/core.php @@ -70,6 +70,9 @@ * - `renderer` - string - The class responsible for rendering uncaught exceptions. If you choose a custom class you * should place the file for that class in app/Lib/Error. This class needs to implement a render method. * - `log` - boolean - Should Exceptions be logged? + * - `skipLog` - array - list of exceptions to skip for logging. Exceptions that + * extend one of the listed exceptions will also be skipped for logging. + * Example: `'skipLog' => array('NotFoundException', 'UnauthorizedException')` * * @see ErrorHandler for more information on exception handling and configuration. */ diff --git a/lib/Cake/Error/ErrorHandler.php b/lib/Cake/Error/ErrorHandler.php index a8867ae88..f5b0decc0 100644 --- a/lib/Cake/Error/ErrorHandler.php +++ b/lib/Cake/Error/ErrorHandler.php @@ -110,9 +110,8 @@ class ErrorHandler { */ public static function handleException(Exception $exception) { $config = Configure::read('Exception'); - if (!empty($config['log'])) { - CakeLog::write(LOG_ERR, self::_getMessage($exception)); - } + self::_log($exception, $config); + $renderer = $config['renderer']; if ($renderer !== 'ExceptionRenderer') { list($plugin, $renderer) = pluginSplit($renderer, true); @@ -159,6 +158,28 @@ class ErrorHandler { return $message; } +/** + * Handles exception logging + * + * @param Exception $exception + * @param array $config + * @return boolean + */ + protected static function _log(Exception $exception, $config) { + if (empty($config['log'])) { + return false; + } + + if (!empty($config['skipLog'])) { + foreach ((array)$config['skipLog'] as $class) { + if ($exception instanceof $class) { + return false; + } + } + } + return CakeLog::write(LOG_ERR, self::_getMessage($exception)); + } + /** * Set as the default error handler by CakePHP. Use Configure::write('Error.handler', $callback), to use your own * error handling methods. This function will use Debugger to display errors when debug > 0. And diff --git a/lib/Cake/Test/Case/Error/ErrorHandlerTest.php b/lib/Cake/Test/Case/Error/ErrorHandlerTest.php index 4b150de50..851de4869 100644 --- a/lib/Cake/Test/Case/Error/ErrorHandlerTest.php +++ b/lib/Cake/Test/Case/Error/ErrorHandlerTest.php @@ -195,8 +195,6 @@ class ErrorHandlerTest extends CakeTestCase { * @return void */ public function testHandleException() { - $this->skipIf(file_exists(APP . 'app_error.php'), 'App error exists cannot run.'); - $error = new NotFoundException('Kaboom!'); ob_start(); ErrorHandler::handleException($error); @@ -210,8 +208,6 @@ class ErrorHandlerTest extends CakeTestCase { * @return void */ public function testHandleExceptionLog() { - $this->skipIf(file_exists(APP . 'app_error.php'), 'App error exists cannot run.'); - if (file_exists(LOGS . 'error.log')) { unlink(LOGS . 'error.log'); } @@ -224,8 +220,37 @@ class ErrorHandlerTest extends CakeTestCase { $this->assertRegExp('/Kaboom!/', $result, 'message missing.'); $log = file(LOGS . 'error.log'); - $this->assertRegExp('/\[NotFoundException\] Kaboom!/', $log[0], 'message missing.'); - $this->assertRegExp('/\#0.*ErrorHandlerTest->testHandleExceptionLog/', $log[2], 'Stack trace missing.'); + $this->assertContains('[NotFoundException] Kaboom!', $log[0], 'message missing.'); + $this->assertContains('ErrorHandlerTest->testHandleExceptionLog', $log[2], 'Stack trace missing.'); + } + +/** + * test handleException generating log. + * + * @return void + */ + public function testHandleExceptionLogSkipping() { + if (file_exists(LOGS . 'error.log')) { + unlink(LOGS . 'error.log'); + } + Configure::write('Exception.log', true); + Configure::write('Exception.skipLog', array('NotFoundException')); + $notFound = new NotFoundException('Kaboom!'); + $forbidden = new ForbiddenException('Fooled you!'); + + ob_start(); + ErrorHandler::handleException($notFound); + $result = ob_get_clean(); + $this->assertRegExp('/Kaboom!/', $result, 'message missing.'); + + ob_start(); + ErrorHandler::handleException($forbidden); + $result = ob_get_clean(); + $this->assertRegExp('/Fooled you!/', $result, 'message missing.'); + + $log = file(LOGS . 'error.log'); + $this->assertNotContains('[NotFoundException] Kaboom!', $log[0], 'message should not be logged.'); + $this->assertContains('[ForbiddenException] Fooled you!', $log[0], 'message missing.'); } /** @@ -257,8 +282,6 @@ class ErrorHandlerTest extends CakeTestCase { * @return void */ public function testHandleFatalErrorPage() { - $this->skipIf(file_exists(APP . 'app_error.php'), 'App error exists cannot run.'); - $line = __LINE__; ob_start(); @@ -286,8 +309,6 @@ class ErrorHandlerTest extends CakeTestCase { * @return void */ public function testHandleFatalErrorLog() { - $this->skipIf(file_exists(APP . 'app_error.php'), 'App error exists cannot run.'); - if (file_exists(LOGS . 'error.log')) { unlink(LOGS . 'error.log'); }