Handling errors in Zend Framework
March 2, 2009 – 6:20 pm Tags: PHP, Zend FrameworkIn Zend Framework based applications, error handling is typically done using the error controller, but there are different ways to send the execution to it – some better than others.
Let’s look at some ways to trigger the error controller and how to have it handle different error conditions.
Error controller structure
Let’s quickly cover the basics of the error controller first:
- To enable the error controller, you need to set throwExceptions to false in the front controller:
$fc->throwExceptions(false);
- The Zend Framework Reference Guide has a chapter on the Error Controller where you can learn the basics
Now, how to structure your error controller?
The easiest way out is, of course, to just handle everything in the errorAction method. However, it will be easier to understand the controller, if you separate different error types into separate actions. This also allows us to easily have error-specific code without bloating the errorAction method too much, in addition to allowing us to easily render error-specific view scripts.
class ErrorController extends Zend_Controller_Action { public function errorAction() { $error = $this->_getParam('error_handler'); switch(get_class($error->exception)) { case 'PageNotFoundException': $this->_forward('page-not-found'); break; case 'NotAuthorizedException': $this->_forward('not-authorized'); break; default: //put some default handling logic here break; } } public function pageNotFoundAction() { //goes here if the page was not found } public function notAuthorizedAction() { //goes here if the user has no access to a page } }
So in the above example, the errorAction would be used to determine the type of the error, and then the request would be forwarded to the respective action. Errors that don’t have a specific action for them can have some generic handling in errorAction.
Triggering the error controller
The most common approach to trigger the error controller is to simply forward the request to it in an erroneous condition:
class SomeController extends Zend_Controller_Action { public function someAction() { if($this->_getParam('foo',false)) { //parameter present - ok } else { //parameter not present - error $this->_forward('some-error', 'error'); } } }
While simple, this approach has a small flaw: The forwarding code is essentially creating a coupling between this controller and the error controller!
If you want to make your code easily re-usable, this is a no-no. By forwarding to a specific action, you are requiring anyone who wants to use the code to implement an error controller with the actions your code requires.
A better approach would be to use exceptions. Instead of forwarding, you throw an exception:
class SomeController extends Zend_Controller_Action { public function someAction() { if($this->_getParam('foo',false)) { //parameter present - ok } else { //parameter not present - error throw new ParameterNotFoundException('oh no!'); } } }
This time we are throwing a custom exception called ParameterNotFoundException. By doing this, we allow the normal error handling code of the framework to take over: the error is caught, and the request is forwarded to the error controller.
Now you can add some code in the error controller to handle this kind of exceptions. Or maybe your project does not need custom handling for this exception, so you can simply use the generic handling code for it.
In closing
There’s not much to error handling in ZF thanks to the ready components that make it really easy. Just throw an exception, and write some code in the error controller to handle it. As a rule of thumb, you should at least log the exceptions that get as far as the error controller!
Further reading:
There are lots of other posts about Zend Framework in this blog


48 Responses to “Handling errors in Zend Framework”
just testing the speed of this post
By elmo on Mar 3, 2009
Great post as usual
By Federico on Mar 3, 2009
Great post. I shall update my post on CSRF protection to mention your post and using exceptions rather than the _forward method.
By Tom Graham on Mar 3, 2009
Good writing!
Though, how do you get to use the ErrorController::notAuthorizedAction()?
By Iulian on Mar 4, 2009
You can use the exception property of the error handler to see what type of exception was thrown. Then you just do $this->_forward(‘notAuthorizedAction’), if the exception is of the type for that.
By Jani Hartikainen on Mar 4, 2009
Updated the code example to show comparing the exception type and forwarding to the appropriate action
By Jani Hartikainen on Mar 4, 2009
Great one dude! You’ve just win a place in my RSS
.
By Pacek on Mar 4, 2009
Where would you declare the exception class ?
In the same file as the SomeController class, in a separate file ?
By Yann on Mar 5, 2009
As per usual PHP conventions, one class per file.
By Jani Hartikainen on Mar 5, 2009
Awesome! A really genious ErrorHandling. What kinds of Exception could be exist?
ParameterNotFoundException who knows some more?
PageNotFoundException?
By Stormbind on Mar 6, 2009
What about handling errors that do not come from controllers but Authentication Plugin::preDispatch() that extends Zend_Controller_Plugin_Abstract. In this way I get kicked out from dispatch loop with this exception:
“Test_Exception: NOT_AUTHORIZED in library\Test\Controller\Plugin\Auth.php on line 32
1 {main}( ) ..\index.php:0
2 Zend_Controller_Front->dispatch( ) ..\index.php:42″
how to walk around it?
By kido on Mar 8, 2009
kido, as far as I know, any exceptions thrown in controller plugins, or action helpers or any other, should be caught by the front controller.
This is assuming you have throwExceptions set to false as mentioned in the post.
By Jani Hartikainen on Mar 8, 2009
Nice post Jani
Again, very clear and thoughtful.
I wrote my own ErrorController too, this is very powerful to control every errors thrown to the user face when the application is not used by a dev
Regards,
Naunaud.
By Naunaud on Mar 8, 2009
Hi Jani
The error was my fault because I mistyped in a list of allowed controllers. I was throwing this exception twice. One exiting loop was thrown in preDispatching of error controller.
But my problem is: when I’m throwing “NotAuthorizedException” from preDispatch plugin the exception is registered but an action is still executed (probably coz ErrorHendler is a postDispatch).
I think that throwing exception(and dealing with them in proper controller) would be better than redirecting, but I can’t do it simple way.
Cheers, and many thnx
By kido on Mar 8, 2009
I’ve got a strange issue coming up with this solution. The following will throw an exception saying the action cannot be found:
$this->_forward(‘pageNotFound’);
public function pageNotFoundAction() {}
However, if I remove camelcasing, it works:
$this->_forward(‘pagenotfound’);
public function pagenotfoundAction() {}
By Kimmo on May 1, 2009
Yeah that’s my mistake.. actually you should not use camelcasing when forwarding – use dashes.
for example:
public function camelCasedAction()
$this->_forward(‘camel-cased’)
I’ve updated the examples to show the correct way to do forwarding.
By Jani Hartikainen on May 1, 2009
Is it possible to create a global exception handler, that will work without manually throwing exceptions in the controller?
By Snowcore on May 6, 2009
How do you create a custom exception such as ParameterNotFoundException?
class ParameterNotFoundException extends Zend_Controller_Exception
{}
or something like that. I’m trying to generate a exception when I test for:
if(!$acl->isAllowed($roleName,$resourceName,$privilageName)){
throw new Zend_Controller_Action_Exception(‘Testing action exception’, 404);
$request->setModuleName(‘default’)
->setControllerName(‘Error’)
->setActionName(‘error’);
}
but instead of going to the error controller I get a message: Uncaught exception ‘Zend_Controller_Action_Exception’
so if you could point me in the right direction into creating my own custom exception classes I’ll appreciate it very much!
By Fabian on May 7, 2009
Snowcore: The error controller will work even if you don’t throw exceptions yourself. Any exceptions thrown by any code will be caught by the front controller (if you have throwExceptions set to false) and forwarded to the error controller.
You could also use set_exception_handler.
Fabian: you must actually throw your custom exception. The code you show is throwing a Zend_Controller_Action_Exception.
By Jani Hartikainen on May 7, 2009
So how do I go about creating the new custom exception class? So I can stap throwing my own custom exceptions.
Thanks,
Fabian
By Fabian on May 8, 2009
Ah sorry, misunderstood your problem. Yes, the code you showed for creating the exception should work, but you may want to inherit from just Exception.
By Jani Hartikainen on May 8, 2009
Sorry to keep bugging you like this , but I created the custom execption at:
Library/Zend/authorizeException.php
class Zend_AuthorizeException extends Exception
{}
so when I do this:
throw new Zend_AuthorizeException(‘Testing exception’, 404);
I get a fatal error: Uncaught exception ‘Zend_AuthorizeException’.
It’s like it never entered the error_handling plugin.
I checked that the throwExceptions = false; and Also added this to my bootstrap just to make sure.
$frontController->throwExceptions(false);
By Fabian on May 8, 2009
Hi,
What about errors/exceptions the application may encounter BEFORE the front controller dispatches? For example, database connection is done prior to front controller dispatch, but what if, when attempting to connect to database you get an exception? How would you route to the error controller?
By stefan on May 11, 2009
Some use a controller plugin to initialize their DBs etc., which would solve this. The alternative to that is putting your DB connection code in a try-catch block.
By Jani Hartikainen on May 12, 2009
Thanks for your answer,
I knew about the controller plugin solution to this problem but I always go with a bootstrap class in my zend framework powered applications. I also found this http://www.nabble.com/Process-to-an-ErrorController-when-an-exception-has-been-catched-td19607161.html which I even tried at some point but with no success.
By stefan on May 12, 2009
Just a small question:
Where would you put the custom Exception classes in your directory structure? If I throw an exception, it is going to look for an exception, would anybody know where and how to handle this?
By Yorian on Nov 9, 2009
You would put the class to the library directory, for example library/Foobar/Exception.php
By Jani Hartikainen on Nov 9, 2009
Sounds a bit like a “dirty” solution (just because this is the include path). Would it be possible to use the auto loader zend uses automatically?
By Yorian on Nov 9, 2009
You typically put “infrastructure” code such as custom exceptions in the library dir. It will work just fine with ZF autoloader, assuming you name your class correctly and you’ve configured the autoloader right.
By Jani Hartikainen on Nov 9, 2009
Somehow it doesn’t seem to work with me, just some information:
My directory structure:
/application
/modules
/default
/Exception
/Exception/UserNotFound.php
In a certain model (also in the default module) I throw the exception like this:
throw new Exception_UserNotFound(‘User could not be found’);
In UserNotFound.php I have the following:
class Exception_UserNotFound extends Zend_Exception {}
By Yorian on Nov 9, 2009
BTW, I get the following error:
Fatal error: Class ‘Exception_UserNotFound’ not found in C:\xampp\server\application\modules\default\controllers\UserController.php on line 22
By Yorian on Nov 9, 2009
Yes there are different ways to send the execution to it and some better than public works handling is typically.
By public works energy on Apr 19, 2010
that default error is not good how can i show my error message by detail my error message always show Application error so i can’t know where is my error and which error is occured
By batmagnai on Jul 8, 2010
why this error controller is not accessing by simply typing as url

application/admin/error
although this controller exist…
it shows error
Fatal error: Uncaught exception ‘Zend_Controller_Dispatcher_Exception’ with message ‘Invalid controller class (“Admin_ErrorController”)’ in C:\xampp\htdocs\asiandirectors\library\Zend\Controller\Dispatcher\Standard.php……..
plz help me out …its urgent
By richa on Jul 12, 2010
richa, I’d suggest seeking help on the #zftalk irc channel on irc.freenode.net
By Jani Hartikainen on Jul 15, 2010
Hi
How do I stop ZF from rendering the output in the Action that the Exception is thrown?
I have a an action which may throw an Exception, the Exception is handled in my ErrorController. The problem is that the output from the orignal Exception is shown along with any output from the ErrorController.
Is this expected or have I done something wrong?
By Jake Noble on Aug 21, 2010
Jake, when an exception happens in one of your controllers, it should go to the error controller without any output from the current controller. So yeah, sounds like there could be a problem in your code. Explicitly rendering or echoing stuff, perhaps?
By Jani Hartikainen on Aug 22, 2010
Jani, thanks for the response. The Exception is not being thrown in a controller, but in a plug in. The plug in loads and checks my Acl. I then throw an Exception if something is wrong.
If I throw the same Exception from within a controller it works fine. Any ideas on how to do this from within my plug in?
By Jake Noble on Aug 23, 2010
It seems others have this issue too, but I have yet to find a solution so I asked about it on Stack Overflow, in case your interested … http://stackoverflow.com/questions/3548282/handling-exceptions-thrown-in-zend-frameworks-controller-plugins
By Jake Noble on Aug 23, 2010
I posted an answer (or at least an idea) to the SO question
By Jani Hartikainen on Aug 24, 2010
I have a an action which may throw an Exception, the Exception is handled in my ErrorController. The problem is that the output from the orignal Exception is shown along with any output from the ErrorController.
By Arkadaşlık sitesi on Aug 24, 2010
Folks, kind of related to this, if you’re using Action Helpers w/ hooks to autorun, read my issue on Stack Overflow:
http://stackoverflow.com/questions/4076578/do-action-helpers-with-hooks-to-auto-run-throw-exceptions-or-not/4082325
You want to make sure to trap exceptions.
By Joe Devon on Nov 3, 2010
güzel bi paylaşım olmuş.
yazanlara teşekkürler
By blackberry servisi on Jan 12, 2011
I am having a problem when typing as url app, there apparently is the controller, but it displays an error flag for some reason
By Simon on Feb 11, 2011