如何捕捉在EVENT_DISPATCH监听器中抛出的异常


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

是否有任何方法可以在EVENT_DISPATCH侦听器中抛出异常?

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");
        });
    }
}

我有一种常见的服务ForbiddenException的方式,如设置403,返回JSON等…所有的逻辑都连接到MvcEvent::EVENT_DISPATCH_ERROR监听器。如何将ForbiddenException转移到调度错误侦听器内的侦听器?从调度侦听器抛出它会导致未捕获异常错误…

任何帮助或提示如何克服它将不胜感激!

你应该使用shareevent管理器来绑定事件。像这样:

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
         }
    );
}

我建议用一个可调用的类代替匿名函数,一旦它像那样工作

如果我理解正确,您希望附加到EVENT_DISPATCH_ERROR事件的侦听器来处理正在引发的异常。

要做到这一点,而不是仅仅throw异常,您应该自己触发调度错误事件,并将异常的实例作为它的一个参数,例如…

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);
        });
    }
}

一旦触发,你的错误监听器应该接管并处理你的异常