1. * When debug < 1 cakeError() will render 404 or 500 errors. * * @package cake * @subpackage cake.cake.libs */ class ErrorHandler { /** * Controller instance. * * @var Controller * @access public */ public $controller = null; /** * Class constructor. * * @param string $method Method producing the error * @param array $messages Error messages */ function __construct(Exception $exception) { App::import('Core', 'Sanitize'); $this->controller = $this->_getController($exception); if (method_exists($this->controller, 'apperror')) { return $this->controller->appError($exception); } $method = Inflector::variable(str_replace('Exception', '', get_class($exception))); if (!in_array($method, get_class_methods($this))) { $method = 'error'; } if ($method !== 'error') { if (Configure::read('debug') == 0) { $code = $exception->getCode(); $parentClass = get_parent_class($this); if ($parentClass != 'ErrorHandler') { $method = 'error404'; } $parentMethods = (array)get_class_methods($parentClass); if (in_array($method, $parentMethods)) { $method = 'error404'; } if ($code == 500) { $method = 'error500'; } } } $this->method = $method; $this->error = $exception; } /** * Get the controller instance to handle the exception. * Override this method in subclasses to customize the controller used. * This method returns the built in `CakeErrorController` normally, or if an error is repeated * a bare controller will be used. * * @param Exception $exception The exception to get a controller for. * @return Controller */ protected function _getController($exception) { static $__previousError = null; App::import('Controller', 'CakeError'); if ($__previousError != $exception) { $__previousError = $exception; $controller = new CakeErrorController(); } else { $controller = new Controller(); $controller->viewPath = 'errors'; } return $controller; } /** * Set as the default exception handler by the CakePHP bootstrap process. * If you wish you use a custom default exception handler use set_exception_handler() * in your app/config/bootstrap.php. * * @return void * @see http://php.net/manual/en/function.set-exception-handler.php */ public static function handleException(Exception $exception) { $error = new ErrorHandler($exception); $error->render(); } /** * Renders the response for the exception. * * @return void */ public function render() { call_user_func_array(array($this, $this->method), array($this->error)); } /** * Displays an error page (e.g. 404 Not found). * * @param array $params Parameters for controller */ public function error(Exception $error) { $this->error404($error); } /** * Convenience method to display a 404 page. * * @param array $params Parameters for controller */ public function error404($error) { $message = $error->getMessage(); if (Configure::read('debug') == 0) { $message = __('Not Found'); } $url = Router::normalize($this->controller->request->here); $this->controller->response->statusCode(404); $this->controller->set(array( 'code' => 404, 'name' => $message, 'url' => h($url), )); $this->_outputMessage('error404'); } /** * Convenience method to display a 500 page. * * @param array $params Parameters for controller */ public function error500($params) { $url = Router::normalize($this->controller->request->here); $this->controller->response->statusCode(500); $this->controller->set(array( 'name' => __('An Internal Error Has Occurred'), 'message' => h($url), )); $this->_outputMessage('error500'); } /** * Renders the Missing Controller web page. * * @param array $params Parameters for controller */ public function missingController($error) { $controllerName = str_replace('Controller', '', $error->getMessage()); $this->controller->set(array( 'controller' => $error->getMessage(), 'controllerName' => $controllerName )); $this->_outputMessage('missingController'); } /** * Renders the Missing Action web page. * * @param array $params Parameters for controller */ public function missingAction($error) { $message = $error->getMessage(); list($controllerName, $action) = explode('::', $message); $this->controller->set(array( 'controller' => $controllerName, 'action' => $action, )); $this->_outputMessage('missingAction'); } /** * Renders the Private Action web page. * * @param array $params Parameters for controller */ public function privateAction($error) { $message = $error->getMessage(); list($controllerName, $action) = explode('::', $message); $this->controller->set(array( 'controller' => $controllerName, 'action' => $action )); $this->_outputMessage('privateAction'); } /** * Renders the Missing Table web page. * * @param array $params Parameters for controller */ public function missingTable($error) { $this->controller->header("HTTP/1.0 500 Internal Server Error"); $this->controller->set(array( 'model' => $error->getModel(), 'table' => $error->getTable(), )); $this->_outputMessage('missingTable'); } /** * Renders the Missing Database web page. * * @param array $params Parameters for controller */ public function missingDatabase($exception) { $this->controller->header("HTTP/1.0 500 Internal Server Error"); $this->controller->set(array( 'code' => '500', 'title' => __('Scaffold Missing Database Connection') )); $this->_outputMessage('missingScaffolddb'); } /** * Renders the Missing View web page. * * @param array $params Parameters for controller */ public function missingView($error) { $this->controller->set(array( 'file' => $error->getMessage(), )); $this->_outputMessage('missingView'); } /** * Renders the Missing Layout web page. * * @param array $params Parameters for controller */ public function missingLayout($error) { $this->controller->layout = 'default'; $this->controller->set(array( 'file' => $error->getMessage(), )); $this->_outputMessage('missingLayout'); } /** * Renders the Database Connection web page. * * @param array $params Parameters for controller */ public function missingConnection($error) { $this->controller->header("HTTP/1.0 500 Internal Server Error"); $this->controller->set(array( 'code' => '500', 'model' => $error->getMessage(), )); $this->_outputMessage('missingConnection'); } /** * Renders the Missing Helper file web page. * * @param array $params Parameters for controller */ public function missingHelperFile($error) { list($class, $ext) = explode('.', $error->getMessage()); $this->controller->set(array( 'className' => Inflector::camelize($class), 'file' => $error->getMessage() )); $this->_outputMessage('missingHelperFile'); } /** * Renders the Missing Helper class web page. * * @param array $params Parameters for controller */ public function missingHelperClass($error) { $class = $error->getMessage(); $file = Inflector::underscore(str_replace('Helper', '', $error->getMessage())) . '.php'; $this->controller->set(array( 'className' => $class, 'file' => $file, )); $this->_outputMessage('missingHelperClass'); } /** * Renders the Missing Behavior file web page. * * @param array $params Parameters for controller */ public function missingBehaviorFile($error) { list($class, $ext) = explode('.', $error->getMessage()); $this->controller->set(array( 'className' => Inflector::camelize($class), 'file' => $error->getMessage() )); $this->_outputMessage('missingBehaviorFile'); } /** * Renders the Missing Behavior class web page. * * @param array $params Parameters for controller */ public function missingBehaviorClass($error) { $class = $error->getMessage(); $file = Inflector::underscore(str_replace('Behavior', '', $error->getMessage())) . '.php'; $this->controller->set(array( 'className' => $class, 'file' => $file, )); $this->_outputMessage('missingBehaviorClass'); } /** * Renders the Missing Component file web page. * * @param array $params Parameters for controller */ public function missingComponentFile($error) { list($class, $ext) = explode('.', $error->getMessage()); $this->controller->set(array( 'className' => Inflector::camelize($class), 'file' => $error->getMessage() )); $this->_outputMessage('missingComponentFile'); } /** * Renders the Missing Component class web page. * * @param array $params Parameters for controller */ public function missingComponentClass($error) { $class = $error->getMessage(); $file = Inflector::underscore(str_replace('Component', '', $error->getMessage())) . '.php'; $this->controller->set(array( 'className' => $class, 'file' => $file, )); $this->_outputMessage('missingComponentClass'); } /** * Output message * */ protected function _outputMessage($template) { $this->controller->render($template); $this->controller->afterFilter(); $this->controller->response->send(); } }