View Source

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[{zone-template-instance:ZFDEV:Zend Proposal Zone Template}

{zone-data:component-name}
Zend_Controller_Plugin_ErrorHandler
{zone-data}

{zone-data:proposer-list}
[~ralph]
{zone-data}

{zone-data:revision}
1.1 - 29 April 2007
{zone-data}

{zone-data:overview}
This component is an option easy to use error handler. Only available to ZF > 9.2 since postDispatch() hooks can now run even after an action controller exception.
{zone-data}

{zone-data:references}
{zone-data}

{zone-data:requirements}
Simple component, see code below.
{zone-data}

{zone-data:dependencies}
* Zend_Exception
{zone-data}

{zone-data:operation}

{zone-data}

{zone-data:milestones}
{zone-data}

{zone-data:class-list}
{zone-data}

{zone-data:use-cases}
||UC-01||
{code}

// in the bootstrap
$controller = Zend_Controller_Front::getInstance();
$controller->setControllerDirectory('../application/user/default/controllers')
->registerPlugin(new Zend_Controller_Plugin_ErrorHandler())

// the target ErrorController the plugin will direct errors to (by default)
<?php

class ErrorController extends Zend_Controller_Action
{

protected $_error = null;

public function init()
{
$this->_error = $this->getRequest()->getParam('error_handler');
}

public function errorAction()
{
switch ($this->_error->type) {
case 'EXCEPTION_NO_CONTROLLER':
case 'EXCEPTION_NO_ACTION':
$this->_forward('not-found');
return;
case 'EXCEPTION_OTHER':
$this->_forward('server-error');
return;
}
}

public function UserInputAction()
{
if (defined('APPLICATION_STATE') && APPLICATION_STATE == 'development') {
Zend_Debug::dump($this->_error->exception);
die('DEBUG: died in ' . __FUNCTION__);
} else {
$this->render();
}
}

public function NoAuthAction()
{
if (defined('APPLICATION_STATE') && APPLICATION_STATE == 'development') {
Zend_Debug::dump($this->_error->type);
die('DEBUG: died in ' . __FUNCTION__);
} else {
$this->render();
}
}

public function NotFoundAction()
{
if (defined('APPLICATION_STATE') && APPLICATION_STATE == 'development') {
echo "<pre>Error Request:\n\n</pre>";
Zend_Debug::dump($this->_error->request);
echo "<pre>Exception:\n\n</pre>";
Zend_Debug::dump($this->_error->exception);
die('DEBUG: died in ' . __FUNCTION__);
} else {
$this->_response->setHttpResponseCode(404);
$this->render();
}
}

public function ServerErrorAction()
{
if (defined('APPLICATION_STATE') && APPLICATION_STATE == 'development') {
echo "<pre>Error Request:\n\n</pre>";
Zend_Debug::dump($this->_error->request);
echo "<pre>Exception:\n\n</pre>";
Zend_Debug::dump($this->_error->exception);
die('DEBUG: died in ' . __FUNCTION__);
} else {
$writer = new Zend_Log_Writer_Stream('../application/variable/logs/application_exception.log');
$logger = new Zend_Log($writer);
$logger->log(get_class($exception) . ' -> ' . $exception->getMessage(), Zend_Log::CRIT);
$this->_response->setHttpResponseCode(500);
$this->_response->setBody($this->render());
}
}

}
{code}

{zone-data}

{zone-data:skeletons}
{code}
<?php

/**
* This plugin handles exceptions that might bubble up from the controller or
* from within action controllers.
*
*/
class Zend_Controller_Plugin_ErrorHandler extends Zend_Controller_Plugin_Abstract
{
/**
* Const - No Controller
*/
const EXCEPTION_NO_CONTROLLER = 'EXCEPTION_NO_CONTROLLER';

/**
* Const - No Action
*/
const EXCEPTION_NO_ACTION = 'EXCEPTION_NO_ACTION';

/**
* Const - Other Exception
*/
const EXCEPTION_OTHER = 'EXCEPTION_OTHER';

/**
* $_errorModule
*
* @var string DEFAULT default
*/
protected $_errorModule = 'default';

/**
* $_errorController
*
* @var string DEFAULT error
*/
protected $_errorController = 'error';

/**
* $_errorAction
*
* @var string DEFAULT error
*/
protected $_errorAction = 'error';

/**
* $_insideErrorHandlerLoop
*
* @var bool
*/
protected $_isInsideErrorHandlerLoop = false;

/**
* $_exceptionCountAtFirstEncounter
*
* @var int
*/
protected $_exceptionCountAtFirstEncounter = 0;

/**
* __construct()
*
* @param Array $options
*/
public function __construct(Array $options = array())
{
$this->setErrorHandler($options);
}

/**
* setErrorHandler() - setup the error handling options
*
* @param array $options
* @return Zend_Controller_Plugin_ErrorHandler
*/
public function setErrorHandler(Array $options = array())
{
$this->_errorModule = (isset($options['module'])) ? $options['module'] : 'default';
$this->_errorController = (isset($options['controller'])) ? $options['controller'] : 'error';
$this->_errorAction = (isset($options['action'])) ? $options['action'] : 'error';
return $this;
}

/**
* setErrorHandlerModule() - set the module name for the error handler
*
* @param string $module
* @return Zend_Controller_Plugin_ErrorHandler
*/
public function setErrorHandlerModule($module)
{
$this->_errorModule = (string) $module;
return $this;
}

/**
* setErrorHandlerController()
*
* @param string $controller
* @return Zend_Controller_Plugin_ErrorHandler
*/
public function setErrorHandlerController($controller)
{
$this->_errorController = (string) $controller;
return $this;
}

/**
* setErrorHandlerAction()
*
* @param string $action
* @return Zend_Controller_Plugin_ErrorHandler
*/
public function setErrorHandlerAction($action)
{
$this->_errorAction = (string) $action;
return $this;
}

/**
* postDispatch() - Plugin Hook
*
* @param Zend_Controller_Request_Abstract $request
*/
public function postDispatch(Zend_Controller_Request_Abstract $request)
{
$response = $this->getResponse();

if ($this->_isInsideErrorHandlerLoop) {
$exceptions = $response->getException();
if (count($exceptions) > $this->_exceptionCountAtFirstEncounter) {
$frontController = Zend_Controller_Front::getInstance();
$frontController->throwExceptions(true);
throw array_pop($exceptions);
}
}

// check for an exception AND allow the error handler controller the option to forward
if ( ($response->isException()) && (!$this->_isInsideErrorHandlerLoop) ) {

$error = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS);
$error->request = clone $request;

$this->_isInsideErrorHandlerLoop = true;

$request->setParam('error_handler', $error);

$request->setModuleName($this->_errorModule)
->setControllerName($this->_errorController)
->setActionName($this->_errorAction);

$exceptions = $response->getException();

// get a count of the number of exceptions encountered
$this->_exceptionCountAtFirstEncounter = count($exceptions);

$exception = $exceptions[0];
$exceptionType = get_class($exception);

$error->exception = $exception;

switch ($exceptionType) {
case 'Zend_Controller_Dispatcher_Exception':
$error->type = self::EXCEPTION_NO_CONTROLLER;
break;
case 'Zend_Controller_Exception':
$error->type = self::EXCEPTION_NO_ACTION;
break;
default:
$error->type = self::EXCEPTION_OTHER;
break;
}

$request->setDispatched(false);
}


}
}
{code}
{zone-data}

{zone-template-instance}]]></ac:plain-text-body></ac:macro>