Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling Exceptions thrown in Zend Framework's Controller Plugins

I have an Acl plug-in which extends Zend_Controller_Plugin_Abstract, this plug-in handles all my Acl code.

I want to thrown an Exception in this plug-in, e.g. an Exception_Unauthorised and then handle this in my ErrorController, this way I can use the same Acl plug-in for different applications and use the ErrorController to handle each situation in each application differently - if need be.

The problem is that throwing an Exception in the plug-in does not stop the original Action from executing. So I end up with the original Action's output and the ErrorController output.

How can I get an Exception thrown in a plug-in to stop the original Action from taking place?

Case 1

// This throws the `Exception_NoPermissions`, but it does not get caught by
// `ErrorController`
public function preDispatch(Zend_Controller_Request_Abstract $request)
{       
    parent::preDispatch($request);
    throw new Exception_NoPermissions("incorrect permissions");
}

Case 2

// This behaves as expected and allows me to catch my Exception
public function preDispatch(Zend_Controller_Request_Abstract $request)
{       
    parent::preDispatch($request);
    try
    {
        throw new Exception_NoPermissions("incorrect permissions");
    }
    catch(Exception_NoPermissions $e)
    {

    }
}

Case 3

I think this is where the issue is, by changing the controller.

public function preDispatch(Zend_Controller_Request_Abstract $request)
{       
    parent::preDispatch($request);

    // Attempt to log in the user

    // Check user against ACL

    if(!$loggedIn || !$access)
    {
        // set controller to login, doing this displays the ErrorController output and
        // the login controller
        $request->getControllerName("login");
    }
}
like image 276
Jake N Avatar asked Aug 23 '10 14:08

Jake N


2 Answers

Take a look at this article: http://akrabat.com/zend-framework/handling-exceptions-in-a-front-controller-plugin/

like image 66
BasTaller Avatar answered Oct 05 '22 23:10

BasTaller


I had a quick chat about this on the #zftalk IRC channel, and Ryan Mauger / Bittarman said that currently you would need to manually redirect the user if the exception happens in a plugin.

I also had an idea that maybe you could use a separate plugin to check for an exception. If you look at the ErrorHandler plugin, it checks if the request contains an exception and acts on it.

The problem is that the ErrorHandler fires on routeShutdown, eg. when the request has already finished. If you created a custom plugin which looks at the exception, but runs on preDispatch, it might be possible to automate this task.

Note that you would need to make sure this custom plugin is ran after any plugins that may throw exceptions.

like image 32
Jani Hartikainen Avatar answered Oct 06 '22 00:10

Jani Hartikainen