The Error Controller
Wednesday, October 21, 2009
There are two basic kinds of errors that occur in Zend Framework applications: Page Not Found and Internal Error. These are handled by the error controller.
The ErrorController class is normally stored in the file ErrorController.php inside the application/controllers directory. This convention is followed by the sample application.
The skeleton for the class code is as follows:
class ErrorController extends Zend_Controller_Action { public function errorAction() { // Insert error handling code here } }
Note that the ErrorController is derived from Zend_Controller_Action, as controllers usually are. Note also that the action is error.
The error handling code starts by determining whether the request was an AJAX request; this is important, as standard requests should be greated with a full error page for the benefit of the user, but AJAX requests should receive a terse error message that is easily processed by the calling code.
$isAjaxRequest = $this->getRequest()->isXmlHttpRequest();
Next, it retrieves the error handle in order to get more information about the error:
$errors = $this->_getParam('error_handler');
Then it fetches the log object from the registry; the mechanism by which this is created and stored there is described in the earlier blog post Bootstrapping the Application: a Custom Log Resource Plugin.
$log = Zend_Registry::get('Zend_Log');
There is then a switch statement, that determines which of the two basic kinds of errors has occurred; the skeleton for this statement is:
switch ($errors->type) { case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER: case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION: // 404 error -- controller or action not found // Insert page not found error handling code here break; default: // application error // Insert internal error handling code here break; }
The page not found error is handled as follows: an AJAX request for a non-existent resource is met by a terse error message, while other request receive a more expansive response. The error details are written to the log file.
if ($isAjaxRequest) { $errorMessage = 'ERROR,404'; } else { $this->view->title = 'Page not found'; $this->view->message = 'The page you requested could not be found.'; } $log->info('404 error occured: ' . $this->getRequest()->getRequestUri());
Internal errors are handled in the same fashion:
if ($isAjaxRequest) { $errorMessage = 'ERROR,500'; } else { $this->view->title = 'Application error'; $this->view->message = 'An error occured in the web application.'; } $log->crit('500 error occured: ' . $errors->exception->getMessage());
Finally, if it is an AJAX request, the application disables the layout and view script rendering, then simply echoes the error; otherwise, it passes the error details to the view script:
if ($isAjaxRequest) { $this->_helper->layout->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); echo $errorMessage; } else { $this->view->exception = $errors->exception; $this->view->request = $errors->request; }
The view script is called error.phtml and is stored in the views/scripts/error directory. It contains the following code:
<?php printf('<h1>%s</h1>', $this->title); printf('<p>%s</p>', $this->message); if (APPLICATION_ENV == 'development') { echo '<h2>Exception information:</h2>'; printf('<p><b>Message:</b> %s</p>', $this->exception->getMessage()); echo '<h2>Stack trace:</h2>'; printf('<p>%s</p>', $this->exception->getTraceAsString()); echo '<h3>Request Parameters:</h3>'; printf('<p>%s</p>', var_export($this->request->getParams(), 1)); }
Note how the function checks the APPLICATION_ENV constant to see whether the application is in a development environment; in that case, it will supply a more extensive on screen error message to assist with debugging.

Practical Web 2.0 Applications with PHP (Expert's Voice) by Quentin Zervaas
Beginning Databases with PostreSQL: From Expert to Professional 2nd Edition: From Novice to Professional by Neil Matthew, Richard Stones