4

I have a module Api where I am trying to implement a RESTful API. The problem is that when I throw an exception in that module, I would like the exception to be thrown and not handled by the error controller in the default module.

Is it possible to disable the error controller for just a specific module in Zend Framework?

1 Answer 1

4

Using the following method you could disable the error handler for a specific module. In this example, I will call your RESTful module rest.

First, create a new plugin in your application. For the example, this will be Application_Plugin_RestErrorHandler. Add the following code to application/plugins/RestErrorHandler.php

class Application_Plugin_RestErrorHandler extends Zend_Controller_Plugin_Abstract
{
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        $module = $request->getModuleName();

        // don't run this plugin unless we are in the rest module
        if ($module != 'rest') return ;

        // disable the error handler, this has to be done prior to dispatch()
        Zend_Controller_Front::getInstance()->setParam('noErrorHandler', true); 
    }
}

Next, in your module Bootstrap for the rest module, we will register the plugin. This is in modules/rest/Bootstrap.php. Since all module bootstraps are executed regardless of the current module, it could go in your main bootstrap, but I like to register plugins related to a specific module in that module's bootstrap.

protected function _initPlugins()
{
    $bootstrap = $this->getApplication();
    $bootstrap->bootstrap('frontcontroller');
    $front = $bootstrap->getResource('frontcontroller');

    // register the plugin
    $front->registerPlugin(new Application_Plugin_RestErrorHandler());
}

Another possibility would be to keep the error handler, but use a module specific error handler. This way, the error handler for your rest module could behave differently and output a REST friendly error.

To do that, copy ErrorController.php to modules/rest/controllers/ErrorController.php and rename the class to Rest_ErrorController. Next, copy the view script for the error controller to modules/rest/views/scripts/error/error.phtml.

Customize error.phtml to your liking so the error message uses the same JSON/XML format used by your rest module.

Then, we will make a slight tweak to the plugin above. What we will do is tell Zend_Controller_Front to use ErrorController::errorAction from the rest module instead of the default module. If you wanted, you could even use a different controller than ErrorController. Change the plugin to look like the following:

class Application_Plugin_RestErrorHandler extends Zend_Controller_Plugin_Abstract
{
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        $module = $request->getModuleName();

        if ($module != 'rest') return ;

        $errorHandler = Zend_Controller_Front::getInstance()
                        ->getPlugin('Zend_Controller_Plugin_ErrorHandler');

        // change the error handler being used from the one in the default module, to the one in the rest module
        $errorHandler->setErrorHandlerModule($module); 
    }
}

With the above method, you still need to register the plugin in Bootstrap.

Hope that helps.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, this helped me a lot. I want to just display an error XML response when an exception is thrown.
I think in that case then you want to use the second method. Otherwise the exception will go all the way back to the front controller and with the error handling turned off I think you will ultimately get an exception throw back to PHP and in a production environment you usually just end up with a 500 server error. If you set up the error handler for the module, you can have the controller possibly log the exception in case it wasn't caused by bogus user input, and the error view script can just unconditionally show an XML response representing an error state.
Just thought about it a little more, you could still use the default error handler from the default module, just assign the current module to the view from ErrorController, and either show the XML when the module is rest, or you could have the error controller render error.xml.phtml or something like that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.