summaryrefslogtreecommitdiffstats
path: root/system
diff options
context:
space:
mode:
authorAndrey Andreev <narf@devilix.net>2014-10-28 22:46:45 +0100
committerAndrey Andreev <narf@devilix.net>2014-10-28 22:46:45 +0100
commit4b838af40d77684539dd40461bd92e6e453fe675 (patch)
treee998edf78ebbd6e1784e858789ad4fa49a159fd1 /system
parent2a86f07f4639c0a25df977c00cef23b8f34f9475 (diff)
Add a real exception handler
Close #1590 Close #3200
Diffstat (limited to 'system')
-rw-r--r--system/core/CodeIgniter.php3
-rw-r--r--system/core/Common.php45
-rw-r--r--system/core/Exceptions.php38
3 files changed, 77 insertions, 9 deletions
diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php
index e3d3a1ffb..88e730bc3 100644
--- a/system/core/CodeIgniter.php
+++ b/system/core/CodeIgniter.php
@@ -132,7 +132,8 @@ if ( ! is_php('5.4'))
* Define a custom error handler so we can log PHP errors
* ------------------------------------------------------
*/
- set_error_handler('_exception_handler');
+ set_error_handler('_error_handler');
+ set_exception_handler('_exception_handler');
register_shutdown_function('_shutdown_handler');
/*
diff --git a/system/core/Common.php b/system/core/Common.php
index 8bc9d015e..4277ef5b1 100644
--- a/system/core/Common.php
+++ b/system/core/Common.php
@@ -570,17 +570,17 @@ if ( ! function_exists('set_status_header'))
// --------------------------------------------------------------------
-if ( ! function_exists('_exception_handler'))
+if ( ! function_exists('_error_handler'))
{
/**
- * Exception Handler
+ * Error Handler
*
- * This is the custom exception handler that is declared at the top
- * of CodeIgniter.php. The main reason we use this is to permit
+ * This is the custom error handler that is declared at the (relative)
+ * top of CodeIgniter.php. The main reason we use this is to permit
* PHP errors to be logged in our own log files since the user may
- * not have access to server logs. Since this function
- * effectively intercepts PHP errors, however, we also need
- * to display errors based on the current error_reporting level.
+ * not have access to server logs. Since this function effectively
+ * intercepts PHP errors, however, we also need to display errors
+ * based on the current error_reporting level.
* We do that with the use of a PHP error template.
*
* @param int $severity
@@ -589,7 +589,7 @@ if ( ! function_exists('_exception_handler'))
* @param int $line
* @return void
*/
- function _exception_handler($severity, $message, $filepath, $line)
+ function _error_handler($severity, $message, $filepath, $line)
{
$is_error = (((E_ERROR | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity);
@@ -632,6 +632,35 @@ if ( ! function_exists('_exception_handler'))
// ------------------------------------------------------------------------
+if ( ! function_exists('_exception_handler'))
+{
+ /**
+ * Exception Handler
+ *
+ * Sends uncaught exceptions to the logger and displays them
+ * only if display_errors is On so that they don't show up in
+ * production environments.
+ *
+ * @param Exception $exception
+ * @return void
+ */
+ function _exception_handler($exception)
+ {
+ $_error =& load_class('Exceptions', 'core');
+ $_error->log_exception('error', 'Exception: '.$exception->getMessage(), $exception->getFile(), $exception->getLine());
+
+ // Should we display the error?
+ if (ini_get('display_errors'))
+ {
+ $_error->show_exception($exception);
+ }
+
+ exit(1); // EXIT_ERROR
+ }
+}
+
+// ------------------------------------------------------------------------
+
if ( ! function_exists('_shutdown_handler'))
{
/**
diff --git a/system/core/Exceptions.php b/system/core/Exceptions.php
index 6324fba2b..0531a4e92 100644
--- a/system/core/Exceptions.php
+++ b/system/core/Exceptions.php
@@ -187,6 +187,44 @@ class CI_Exceptions {
// --------------------------------------------------------------------
+ public function show_exception(Exception $exception)
+ {
+ $templates_path = config_item('error_views_path');
+ if (empty($templates_path))
+ {
+ $templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
+ }
+
+ $message = $exception->getMessage();
+ if (empty($message))
+ {
+ $message = '(null)';
+ }
+
+ if (is_cli())
+ {
+ $templates_path .= 'cli'.DIRECTORY_SEPARATOR;
+ }
+ else
+ {
+ set_status_header(500);
+ $templates_path .= 'html'.DIRECTORY_SEPARATOR;
+ }
+
+ if (ob_get_level() > $this->ob_level + 1)
+ {
+ ob_end_flush();
+ }
+
+ ob_start();
+ include($templates_path.'error_exception.php');
+ $buffer = ob_get_contents();
+ ob_end_clean();
+ echo $buffer;
+ }
+
+ // --------------------------------------------------------------------
+
/**
* Native PHP error handler
*