From 0a2c61ec29fb914478627707b9d4a5062c5f4aa2 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Thu, 10 Nov 2011 22:46:01 -0600 Subject: [PATCH] refactoring error handling. --- application/config/error.php | 38 ++++++------ laravel/bootstrap/core.php | 1 + laravel/bootstrap/errors.php | 110 ----------------------------------- laravel/laravel.php | 86 +++++++++++++++++++++++++-- 4 files changed, 99 insertions(+), 136 deletions(-) delete mode 100644 laravel/bootstrap/errors.php diff --git a/application/config/error.php b/application/config/error.php index 9a78e983..a39fcb9c 100644 --- a/application/config/error.php +++ b/application/config/error.php @@ -36,29 +36,22 @@ | Error Handler |-------------------------------------------------------------------------- | - | Because of the various ways of managing error logging, you get complete - | flexibility in Laravel to manage all error logging as you see fit. + | Because of the various ways of managing errors, you get complete freedom + | to manage errors as you desire. Any error that occurs in your application + | will be sent to this Closure. | - | This function will be called when an error occurs in your application. - | You are free to handle the exception any way you want. The severity - | will be a human-readable severity level such as "Parsing Error". + | By default, when error detail is disabled, a generic error page will be + | rendered by the handler. After this handler is complete, the framework + | will stop processing the request and "exit" will be called. | */ - 'handler' => function($exception, $severity, $message, $config) + 'handler' => function($exception, $config) { - if ($config['detail']) + if ( ! $config['detail']) { - $data = compact('exception', 'severity', 'message'); - - $response = Response::view('error.exception', $data)->status(500); + Response::error('500')->send(); } - else - { - $response = Response::error('500'); - } - - $response->send(); }, /* @@ -71,15 +64,18 @@ | be called anytime an error occurs within your application and error | logging is enabled. | - | You may log the error message however you like; however, a simple logging - | solution has been setup for you which will log all error messages to a - | single text file within the application storage directory. + | You may log the error message however you like; however, a simple log + | solution has been setup for you which will log all error messages to + | a single text file within the application storage directory. + | + | Of course, you are free to implement more complex solutions including + | e-mailing the exceptions details to your team, etc. | */ - 'logger' => function($exception, $severity, $message, $config) + 'logger' => function($exception, $config) { - $message = date('Y-m-d H:i:s').' '.$severity.' - '.$message.PHP_EOL; + $message = date('Y-m-d H:i:s').' - '.$exception->getMessage().PHP_EOL; File::append(STORAGE_PATH.'log.txt', $message); } diff --git a/laravel/bootstrap/core.php b/laravel/bootstrap/core.php index 1c055ac7..a1724bef 100644 --- a/laravel/bootstrap/core.php +++ b/laravel/bootstrap/core.php @@ -59,6 +59,7 @@ */ Config::load('application'); Config::load('session'); +Config::load('error'); /** * Bootstrap the application inversion of control container. The IoC diff --git a/laravel/bootstrap/errors.php b/laravel/bootstrap/errors.php deleted file mode 100644 index f1087c3d..00000000 --- a/laravel/bootstrap/errors.php +++ /dev/null @@ -1,110 +0,0 @@ -getFile()); - - return rtrim($e->getMessage(), '.').' in '.$file.' on line '.$e->getLine().'.'; -}; - -/** - * Define a closure that will return a more readable version of the - * severity of an exception. This function will be used by the error - * handler when parsing exceptions. - */ -$severity = function($e) -{ - $levels = array( - 0 => 'Error', - E_ERROR => 'Error', - E_WARNING => 'Warning', - E_PARSE => 'Parsing Error', - E_NOTICE => 'Notice', - E_CORE_ERROR => 'Core Error', - E_CORE_WARNING => 'Core Warning', - E_COMPILE_ERROR => 'Compile Error', - E_COMPILE_WARNING => 'Compile Warning', - E_USER_ERROR => 'User Error', - E_USER_WARNING => 'User Warning', - E_USER_NOTICE => 'User Notice', - E_STRICT => 'Runtime Notice', - ); - - $code = $e->getCode(); - - return (array_key_exists($code, $levels)) ? $levels[$code] : $code; -}; - -/** - * Create the exception handler function. All of the error handlers - * registered by the framework call this closure to avoid duplicate - * code. Each of the formatting closures defined above will be - * passed into the handler for convenient use. - */ -$handler = function($e) use ($message, $severity) -{ - $config = Config::get('error'); - - if ($config['log']) - { - call_user_func($config['logger'], $e, $severity($e), $message($e), $config); - } - - call_user_func($config['handler'], $e, $severity($e), $message($e), $config); - - exit(1); -}; - -/** - * Register the PHP exception handler. The framework throws exceptions - * on every error that cannot be handled. All of those exceptions will - * fall into this closure for processing. - */ -set_exception_handler(function($e) use ($handler) -{ - $handler($e); -}); - -/** - * Register the PHP error handler. All PHP errors will fall into this - * handler, which will convert the error into an ErrorException object - * and pass the exception into the common exception handler. - */ -set_error_handler(function($number, $error, $file, $line) use ($handler) -{ - $handler(new \ErrorException($error, $number, 0, $file, $line)); -}); - -/** - * Register the PHP shutdown handler. This function will be called at - * the end of the PHP script or on a fatal PHP error. If an error has - * occurred, we will convert it to an ErrorException and pass it to - * the common exception handler. - */ -register_shutdown_function(function() use ($handler) -{ - if ( ! is_null($error = error_get_last())) - { - extract($error, EXTR_SKIP); - - $handler(new \ErrorException($message, $type, 0, $file, $line)); - } -}); - -/** - * Turn off all PHP error reporting and display. Since the framework - * will be displaying the exception messages, we don't want PHP to - * display any ugly error information. - */ -error_reporting(-1); - -ini_set('display_errors', 'Off'); \ No newline at end of file diff --git a/laravel/laravel.php b/laravel/laravel.php index b509905e..bb7b1b19 100644 --- a/laravel/laravel.php +++ b/laravel/laravel.php @@ -8,14 +8,90 @@ require 'bootstrap/core.php'; /** - * Register the framework error handling methods and set the error - * reporting levels. This file will register handlers for exceptions, - * errors, and the shutdown event. + * Register the default timezone for the application. This will be + * the default timezone used by all date / timezone functions in + * the entire application. */ -require SYS_PATH.'bootstrap/errors'.EXT; - date_default_timezone_set(Config::$items['application']['timezone']); +/** + * Create the exception handler function. All of the error handlers + * registered by the framework call this closure to avoid duplicate + * code. This Closure will determine if the logging Closure should + * be called, and will pass the exception to the developer defined + * handler in the configuration file. + */ +$handler = function($exception) +{ + $config = Config::get('error'); + + if ($config['log']) + { + call_user_func($config['logger'], $exception, $config); + } + + call_user_func($config['handler'], $exception, $config); + + if ( ! $config['detail']) + { + exit(1); + } +}; + +/** + * Register the PHP exception handler. The framework throws exceptions + * on every error that cannot be handled. All of those exceptions will + * be sent through this closure for processing. + */ +set_exception_handler(function($exception) use ($handler) +{ + $handler($exception); +}); + +/** + * Register the PHP error handler. All PHP errors will fall into this + * handler, which will convert the error into an ErrorException object + * and pass the exception into the common exception handler. + */ +set_error_handler(function($number, $error, $file, $line) use ($handler) +{ + $handler(new \ErrorException($error, $number, 0, $file, $line)); +}); + +/** + * Register the PHP shutdown handler. This function will be called + * at the end of the PHP script or on a fatal PHP error. If an error + * has occured, we will convert it to an ErrorException and pass it + * to the common exception handler for the framework. + */ +register_shutdown_function(function() use ($handler) +{ + if ( ! is_null($error = error_get_last())) + { + extract($error, EXTR_SKIP); + + $handler(new \ErrorException($message, $type, 0, $file, $line)); + } +}); + +/** + * Setting the PHP error reporting level to -1 essentially forces + * PHP to report every error, and is guranteed to show every error + * on future versions of PHP. + */ +error_reporting(-1); + +/** + * If error detail is turned off, we will turn off all PHP error + * reporting and display since the framework will be displaying a + * generic message and we don't want any sensitive details about + * the exception leaking into the views. + */ +if ( ! Config::$items['error']['detail']) +{ + //ini_set('display_errors', 'Off'); +} + /** * Load the session and session manager instance. The session * payload will be registered in the IoC container as an instance