Richard Knop
Richard Knop

Reputation: 83755

How to disable error controller for a specific module

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?

Upvotes: 4

Views: 1701

Answers (1)

drew010
drew010

Reputation: 69977

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.

Upvotes: 4

Related Questions