Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Ability to pass control of caught errors and exceptions to a controller #1849

Closed
wants to merge 8 commits into from

2 participants

@dionysiosarvanitis

To make this possible, a custom CIRuntimeException (similar to CI's error handling logic) can be thrown from within show_error function. By setting also a default exception_handler, catching the CIRuntimeException is not mandatory.

Everything works just like before plus we've added the ability to handle the error from within our controller.

@dchill42

If I understand correctly, I don't think the guys at Ellis are especially fond of throwing exceptions. I believe there is a philosophical reason why CodeIgniter doesn't contain any.

On the bright(?) side, what I think you're trying to achieve here can be accomplished without throwing an actual exception. #1818 offers (amidst various features) error overrides which let you configure a Controller method to handle general, 404, and php errors any way you like.

@dionysiosarvanitis

Yes, I know that (#!)
I'm gonna try your suggestion. The hole branch seems very very interesting. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
11 system/core/CodeIgniter.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -31,8 +31,8 @@
* Loads the base classes and executes the request.
*
* @package CodeIgniter
- * @subpackage CodeIgniter
- * @category Front-controller
+ * @subpackage CodeIgniter
+ * @category Front-controller
* @author EllisLab Dev Team
* @link http://codeigniter.com/user_guide/
*/
@@ -68,10 +68,11 @@
/*
* ------------------------------------------------------
- * Define a custom error handler so we can log PHP errors
+ * Define a custom error and exception handler so we can log PHP errors
* ------------------------------------------------------
*/
- set_error_handler('_exception_handler');
+ set_error_handler('_error_handler');
+ set_exception_handler('_exception_handler');
if ( ! is_php('5.4'))
{
View
58 system/core/Common.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -31,8 +31,8 @@
* Loads the base classes and executes the request.
*
* @package CodeIgniter
- * @subpackage CodeIgniter
- * @category Common Functions
+ * @subpackage CodeIgniter
+ * @category Common Functions
* @author EllisLab Dev Team
* @link http://codeigniter.com/user_guide/
*/
@@ -501,12 +501,12 @@ function set_status_header($code = 200, $text = '')
// --------------------------------------------------------------------
-if ( ! function_exists('_exception_handler'))
+if ( ! function_exists('_error_handler'))
{
/**
- * Exception Handler
+ * Error Handler
*
- * This is the custom exception handler that is declaired at the top
+ * This is the custom error handler that is declaired at the 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
@@ -520,7 +520,7 @@ function set_status_header($code = 200, $text = '')
* @param int
* @return void
*/
- function _exception_handler($severity, $message, $filepath, $line)
+ function _error_handler($severity, $message, $filepath, $line)
{
$_error =& load_class('Exceptions', 'core');
@@ -544,6 +544,50 @@ function _exception_handler($severity, $message, $filepath, $line)
// --------------------------------------------------------------------
+if ( ! function_exists('_exception_handler'))
+{
+ /**
+ * Default Exception Handler
+ * Triggers on uncaught exceptions
+ *
+ * @access private
+ * @return void
+ */
+ function _exception_handler($exception)
+ {
+ $heading = $exception->getHeading();
+ $message = $exception->getMessage();
+
+ parent::log_exception(E_ERROR, $message, $exception->getFile(), $exception->getLine());
+
+ set_status_header($exception->getStatus());
+
+ $_input =& load_class('Input');
+
+ if ($_input->is_ajax_request())
+ {
+ echo $message;
+ }
+ else
+ {
+ if (ob_get_level() > $this->ob_level + 1)
+ {
+ ob_end_flush();
+ }
+ ob_start();
+ include(APPPATH.'errors/'.$exception->getTemplate().'.php');
+ $buffer = ob_get_contents();
+ ob_end_clean();
+
+ echo $buffer;
+ }
+
+ exit;
+ }
+}
+
+// --------------------------------------------------------------------
+
if ( ! function_exists('remove_invisible_characters'))
{
/**
View
49 system/core/Exceptions.php
@@ -18,7 +18,7 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
@@ -29,8 +29,8 @@
* Exceptions Class
*
* @package CodeIgniter
- * @subpackage Libraries
- * @category Exceptions
+ * @subpackage Libraries
+ * @category Exceptions
* @author EllisLab Dev Team
* @link http://codeigniter.com/user_guide/libraries/exceptions.html
*/
@@ -136,19 +136,11 @@ public function show_error($heading, $message, $template = 'error_general', $sta
{
set_status_header($status_code);
- $message = '<p>'.implode('</p><p>', is_array($message) ? $message : array($message)).'</p>';
+ $message = '<p>'.implode('</p><p>', ( ! is_array($message)) ? array($message) : $message).'</p>';
- if (ob_get_level() > $this->ob_level + 1)
- {
- ob_end_flush();
- }
- ob_start();
- include(VIEWPATH.'errors/'.$template.'.php');
- $buffer = ob_get_contents();
- ob_end_clean();
- return $buffer;
+ throw new CIRuntimeException($heading, $message, $template, $status_code, E_ERROR);
}
-
+
// --------------------------------------------------------------------
/**
@@ -185,5 +177,34 @@ public function show_php_error($severity, $message, $filepath, $line)
}
+/**
+ * CIRuntimeException Class
+ *
+ * @package CodeIgniter
+ * @subpackage Libraries
+ * @category Exceptions
+ * @author EllisLab Dev Team
+ * @link http://codeigniter.com/user_guide/libraries/exceptions.html
+ */
+class CIRuntimeException extends Exception {
+
+ protected $heading;
+ protected $template;
+ protected $status_code;
+
+ public function __construct($heading, $message, $template = 'error_general', $status_code = 500, $code = 0, Exception $previous = null)
+ {
+ parent::__construct($message, $code, $previous);
+
+ $this->heading = $heading;
+ $this->template = $template;
+ $this->status_code = $status_code;
+ }
+
+ final public function getHeading(){ return $this->heading; }
+ final public function getTemplate(){ return $this->template; }
+ final public function getStatus(){ return $this->status_code; }
+}
+
/* End of file Exceptions.php */
/* Location: ./system/core/Exceptions.php */
View
2  system/libraries/Driver.php
@@ -240,7 +240,7 @@ public function __call($method, $args = array())
}
$trace = debug_backtrace();
- _exception_handler(E_ERROR, "No such method '{$method}'", $trace[1]['file'], $trace[1]['line']);
+ _error_handler(E_ERROR, "No such method '{$method}'", $trace[1]['file'], $trace[1]['line']);
exit;
}
Something went wrong with that request. Please try again.