How to show a flashMessage raised by an exception

2019-08-12 22:02发布

问题:

I have an exception raised in my service.

This exception is handle by a Listener attached by :

$this->listeners[] = $events->attach(MvcEvent::EVENT_RENDER_ERROR, array($this, 'handleException'));
$this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH_ERROR, array($this, 'handleException'));

Handle Exception designed into flashMessage by:

public function handleException(MvcEvent $event)
{
    $exception = $event->getParam('exception');
    if ($exception) {
        $flashMessenger = new FlashMessenger();
        $flashMessenger->setNamespace('danger');
        $flashMessenger->addMessage($exception->getMessage());

        $event->getViewModel()->setVariable('flashMessages', $flashMessenger->getMessages());
    }
}

Now, with this code how can i stay to the same page where the exception was raised. I can't show the error/template on each exception, i have to keep my users on the same page for confort.

This question is the following part of this one :

Handle Exception in ZF2

回答1:

You can listen for a specific error; if it is found you can then redirect back to the same page to display the flash message.

ZF2 currently does this with the Zend\Mvc\View\Http\RouteNotFoundStrategy, for 404 errors and Zend\Mvc\View\Http\ExceptionStrategy for generic exceptions; so you will need to attach your event's with a higher priority (than 1) so they are executed first.

You should change the controller code (from your original question) to add the exception to the MVC event and manually trigger the dispatch error.

Edit If you wish to cut down the code, the dispatch listener does handle exceptions from the controller by triggering the MvcEvent::EVENT_DISPATCH_ERROR for you. I've not tested this however you should be able to listen for a custom exception, again providing you have a event priority higher that 1.

public function fooAction()
{
    try {
        throw new \Exception('A error occurred');
    } catch (\Exception $e) {

        // Throw a custom exception
        throw new MyCustomException('Some error');
    }
}

Your event listener can now check for this and handle the redirection.

public function handleException(\Zend\Mvc\MvcEvent $event)
{
    $error = $event->getError();
    $exception = $event->getParam('exception');

    if (! $error || ! $exception instanceof MyCustomException) {
       return;
    }

    $serviceManager = $event->getApplication()->getServiceManager();
    $controllerPluginManager = $serviceManager->get('ControllerPluginManager');

    $flashMessenger = $controllerPluginManager->get('FlashMessenger');

    $flashMessenger->setNamespace('danger');
    $flashMessenger->addMessage($exception->getMessage());

    return $controllerPluginManager->get('redirect')->refresh();
}