问题
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!
回答1:
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.
回答2:
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 throw
ing 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
来源:https://stackoverflow.com/questions/38858219/zf3-2-how-to-catch-an-exception-thrown-within-event-dispatch-listener