Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ZF3/2 - how to catch an exception thrown within EVENT_DISPATCH listener?

Is there any way I can serve an exception thrown within EVENT_DISPATCH listener?

class Module
{
    public function onBootstrap(EventInterface $event)
    {
        $application    = $event->getTarget();
        $eventManager   = $application->getEventManager();

        $eventManager->attach(MvcEvent::EVENT_DISPATCH, function(MvcEvent $event) {
            throw new ForbiddenException("403 - Fobidden");
        });
    }
}

I have a common way of serving ForbiddenException like setting 403, returning JSON, etc... All of the logic is attached to MvcEvent::EVENT_DISPATCH_ERROR listener. How can I transfer ForbiddenException to the listener inside the dispatch error listener? Throwing it from dispatch listener causes Uncaught exception error...

Any help or tips how to get over it will be appreciated!

like image 663
hopsey Avatar asked Jan 21 '26 19:01

hopsey


2 Answers

you should use the sharedevent manager to bind the event. Like this :

public function onBootstrap(MvcEvent $e)
{
    $eventManager = $e->getApplication()->getEventManager();
    $moduleRouteListener = new ModuleRouteListener();
    $moduleRouteListener->attach($eventManager);

    $sharedManager = $e->getApplication()->getEventManager()->getSharedManager();
    $sm = $e->getApplication()->getServiceManager();
    $sharedManager->attach(
         'Zend\Mvc\Application', 
         'dispatch.error',
         function($e) use ($sm) {
            //Do what you want here
         }
    );
}

I suggest replacing the anonymous function with a callable class once it work like that.

like image 116
Unex Avatar answered Jan 23 '26 07:01

Unex


If I'm understanding you correctly you want the listener you attached to the EVENT_DISPATCH_ERROR event to handle the exception you're raising.

To do that, instead of just throwing the exception, you should trigger the dispatch error event yourself with an instance of your exception as one of its parameters, eg ...

class Module
{
    public function onBootstrap(EventInterface $event)
    {
        $application    = $event->getTarget();
        $eventManager   = $application->getEventManager();

        $eventManager->attach(MvcEvent::EVENT_DISPATCH, function(MvcEvent $event) use ($eventManager) {
            // set some identifier for your error listener to look for
            $event->setError('forbidden');
            // add an instance of your exception
            $event->setParam('exception', new ForbiddenException("403 - Fobidden"));
            // trigger the dispatch error with your event payload
            $eventManager->trigger(MvcEvent::EVENT_DISPATCH_ERROR, $event);
        });
    }
}

once triggered your error listener should take over and handle your exception

like image 24
Crisp Avatar answered Jan 23 '26 07:01

Crisp



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!