7 * This source file is subject to the new BSD license that is bundled
8 * with this package in the file LICENSE.txt.
9 * It is also available through the world-wide-web at this URL:
10 * http://framework.zend.com/license/new-bsd
11 * If you did not receive a copy of the license and are unable to
12 * obtain it through the world-wide-web, please send an email
13 * to license@zend.com so we can send you a copy immediately.
16 * @package Zend_Controller
18 * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
19 * @license http://framework.zend.com/license/new-bsd New BSD License
22 /** Zend_Controller_Plugin_Abstract */
23 require_once 'Zend/Controller/Plugin/Abstract.php';
26 * Handle exceptions that bubble up based on missing controllers, actions, or
27 * application errors, and forward to an error handler.
29 * @uses Zend_Controller_Plugin_Abstract
31 * @package Zend_Controller
33 * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
34 * @license http://framework.zend.com/license/new-bsd New BSD License
35 * @version $Id: ErrorHandler.php 16202 2009-06-21 18:53:49Z thomas $
37 class Zend_Controller_Plugin_ErrorHandler
extends Zend_Controller_Plugin_Abstract
40 * Const - No controller exception; controller does not exist
42 const EXCEPTION_NO_CONTROLLER
= 'EXCEPTION_NO_CONTROLLER';
45 * Const - No action exception; controller exists, but action does not
47 const EXCEPTION_NO_ACTION
= 'EXCEPTION_NO_ACTION';
50 * Const - Other Exception; exceptions thrown by application controllers
52 const EXCEPTION_OTHER
= 'EXCEPTION_OTHER';
55 * Module to use for errors; defaults to default module in dispatcher
58 protected $_errorModule;
61 * Controller to use for errors; defaults to 'error'
64 protected $_errorController = 'error';
67 * Action to use for errors; defaults to 'error'
70 protected $_errorAction = 'error';
73 * Flag; are we already inside the error handler loop?
76 protected $_isInsideErrorHandlerLoop = false;
79 * Exception count logged at first invocation of plugin
82 protected $_exceptionCountAtFirstEncounter = 0;
87 * Options may include:
92 * @param Array $options
95 public function __construct(Array $options = array())
97 $this->setErrorHandler($options);
101 * setErrorHandler() - setup the error handling options
103 * @param array $options
104 * @return Zend_Controller_Plugin_ErrorHandler
106 public function setErrorHandler(Array $options = array())
108 if (isset($options['module'])) {
109 $this->setErrorHandlerModule($options['module']);
111 if (isset($options['controller'])) {
112 $this->setErrorHandlerController($options['controller']);
114 if (isset($options['action'])) {
115 $this->setErrorHandlerAction($options['action']);
121 * Set the module name for the error handler
123 * @param string $module
124 * @return Zend_Controller_Plugin_ErrorHandler
126 public function setErrorHandlerModule($module)
128 $this->_errorModule
= (string) $module;
133 * Retrieve the current error handler module
137 public function getErrorHandlerModule()
139 if (null === $this->_errorModule
) {
140 $this->_errorModule
= Zend_Controller_Front
::getInstance()->getDispatcher()->getDefaultModule();
142 return $this->_errorModule
;
146 * Set the controller name for the error handler
148 * @param string $controller
149 * @return Zend_Controller_Plugin_ErrorHandler
151 public function setErrorHandlerController($controller)
153 $this->_errorController
= (string) $controller;
158 * Retrieve the current error handler controller
162 public function getErrorHandlerController()
164 return $this->_errorController
;
168 * Set the action name for the error handler
170 * @param string $action
171 * @return Zend_Controller_Plugin_ErrorHandler
173 public function setErrorHandlerAction($action)
175 $this->_errorAction
= (string) $action;
180 * Retrieve the current error handler action
184 public function getErrorHandlerAction()
186 return $this->_errorAction
;
190 * postDispatch() plugin hook -- check for exceptions and dispatch error
191 * handler if necessary
193 * If the 'noErrorHandler' front controller flag has been set,
196 * @param Zend_Controller_Request_Abstract $request
199 public function postDispatch(Zend_Controller_Request_Abstract
$request)
201 $frontController = Zend_Controller_Front
::getInstance();
202 if ($frontController->getParam('noErrorHandler')) {
206 $response = $this->getResponse();
208 if ($this->_isInsideErrorHandlerLoop
) {
209 $exceptions = $response->getException();
210 if (count($exceptions) > $this->_exceptionCountAtFirstEncounter
) {
211 // Exception thrown by error handler; tell the front controller to throw it
212 $frontController->throwExceptions(true);
213 throw array_pop($exceptions);
217 // check for an exception AND allow the error handler controller the option to forward
218 if (($response->isException()) && (!$this->_isInsideErrorHandlerLoop
)) {
219 $this->_isInsideErrorHandlerLoop
= true;
221 // Get exception information
222 $error = new ArrayObject(array(), ArrayObject
::ARRAY_AS_PROPS
);
223 $exceptions = $response->getException();
224 $exception = $exceptions[0];
225 $exceptionType = get_class($exception);
226 $error->exception
= $exception;
227 switch ($exceptionType) {
228 case 'Zend_Controller_Dispatcher_Exception':
229 $error->type
= self
::EXCEPTION_NO_CONTROLLER
;
231 case 'Zend_Controller_Action_Exception':
232 if (404 == $exception->getCode()) {
233 $error->type
= self
::EXCEPTION_NO_ACTION
;
235 $error->type
= self
::EXCEPTION_OTHER
;
239 $error->type
= self
::EXCEPTION_OTHER
;
243 // Keep a copy of the original request
244 $error->request
= clone $request;
246 // get a count of the number of exceptions encountered
247 $this->_exceptionCountAtFirstEncounter
= count($exceptions);
249 // Forward to the error handler
250 $request->setParam('error_handler', $error)
251 ->setModuleName($this->getErrorHandlerModule())
252 ->setControllerName($this->getErrorHandlerController())
253 ->setActionName($this->getErrorHandlerAction())
254 ->setDispatched(false);