A Useful Error Controller Class For Zend Framework Applications
Published by philipnorton42 on Tue, 12/23/2008 - 15:58One useful function of any application is to report on any errors that occurred. Zend Framework comes with a nice error controller system that you can activate by creating an ErrorController class.
The following is an ErrorController class that I use. It detects what sort of error occurred and displays a message to the user. It will also email a detailed report of the error to the server admins.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | class ErrorController extends Zend_Controller_Action { public function errorAction() { // Ensure the default view suffix is used so we always return good // content $this->_helper->viewRenderer->setViewSuffix('phtml'); // Grab the error object from the request $errors = $this->_getParam('error_handler'); 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 $this->getResponse()->setHttpResponseCode(404); $this->view->message = 'Page not found'; $this->view->code = 404; if ($errors->type == Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER) { $this->view->info = sprintf( 'Unable to find controller "%s" in module "%s"', $errors->request->getControllerName(), $errors->request->getModuleName() ); } if ($errors->type == Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION) { $this->view->info = sprintf( 'Unable to find action "%s" in controller "%s" in module "%s"', $errors->request->getActionName(), $errors->request->getControllerName(), $errors->request->getModuleName() ); } break; case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION: default: // application error $this->getResponse()->setHttpResponseCode(500); $this->view->message = 'Application error'; $this->view->code = 500; $this->view->info = $errors->exception; break; } // send a mail to let someone know that there was a problem! $config = Zend_Registry::get('configuration'); $tr = new Zend_Mail_Transport_Smtp($config->smtp); Zend_Mail::setDefaultTransport($tr); $mail = new Zend_Mail(); $emailBody = "An error occurred in the system. The error message contained the following output:\n\n"; $emailBody .= $this->view->message." (".$this->view->code.")\n\n"; $emailBody .= "Zend Error Type: ".$errors->type."\n\n"; $emailBody .= "REQUEST_URI: ".$_SERVER['REQUEST_URI']."\n\n"; if ( isset($_SERVER['HTTP_REFERER']) ) { $emailBody .= "HTTP_REFERER: ".$_SERVER['HTTP_REFERER']."\n\n"; } $emailBody .= "Stack trace: \n\n". $errors->exception->getTraceAsString()."\n\n"; // find the user to blame! $username = Zend_Auth::getInstance()->getIdentity(); $emailBody .= "This error was created by ".$username."."; $mail->setBodyText($emailBody); $mail->setFrom('anAddress@example.com', ''); $mail->addTo($config->adminEmail, $config->adminName); $mail->setSubject('An Error Occured'); // Email $mail->send(); $this->view->title = 'Error!'; $this->view->heading = 'Error!'; // pass the environment to the view script so we can conditionally // display more/less information $this->view->env = $this->getInvokeArg('env'); // pass the actual exception object to the view $this->view->exception = $errors->exception; // pass the request to the view $this->view->request = $errors->request; } |
This error controller relies on certain options that have been set up in your configuration file. Add the following options to your configuration file to get these options working.
1 2 3 | smtp = my.smtpserver.com adminEmail = admin@example.com adminName = 'Your name' |
To enable this just call the throwExceptions() function of the Zend_Controller_Front and pass it a value of false. This will cause the framework to look for an error controller rather than try to print out things.
1 2 | $frontController = Zend_Controller_Front::getInstance(); $frontController->throwExceptions(false); |
Finally, you need to add a view so that your errors will be displayed nicely. This will display more if the environment is set to 'test'.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <h3>Error has happened. Inside this application. Sorry about that.</h3> <p><?=$this->message ?> (<?=$this->code ?>) </p> <? if( $this->env == 'test' ) { if ( isset($this->info ) ) { ?> <? if ( 404 == $this->code ) { ?> <p><b>Reason:</b> <?= $this->info ?></p> <? } elseif (500 == $this->code) { ?> <p>Bad server, naughty server!<br />No donut for you!</p> <p><img src="<?=$this->baseUrl();?>/images/donut.jpg" /></p> <h4>Exception information:</h4> <p><b>Message:</b> <?= $this->info->getMessage() ?></p> <h4>Stack trace:</h4> <pre><?= $this->info->getTraceAsString() ?> |
Comments
Keep working ,great job! :)
sedax (not verified) - Thu, 12/25/2008 - 16:58Very true, but it depends on
philipnorton42 - Tue, 12/23/2008 - 17:16Nice! The only comment I'd
Matthew Weier O... (not verified) - Tue, 12/23/2008 - 16:12Add new comment