2015-04-24 2 views
1

Я простирающийся специальное исключение для все моей обработанного «ошибки приложения»Подайте вспышку конкретного исключения

abstract class AbstractApplicationException extends \Exception 
{ 
    public function __construct(array $context = array()) 
    { 
     $this->context = $context; 
     parent::__construct('exceptions.'.lcfirst(self::classname())); 
    } 
} 

И я использую messages.xx.yml для описания ошибки пользователя

exceptions: 
    incompatibleSettings: Vos réglages ne sont pas compatibles 

I 'd хотел бы автоматически вводить вспышку с переведенным сообщением об исключении (вида AbstractApplicationException), поэтому мне не нужно делать это на всех моих контроллерах

public myControllerAction() 
    try { 
     $someService->someFunction(); 
    } catch (AbstractApplicationException $e) { 
     $flashBag->add('error', 
      $this->get('translator')->trans(
       $e->getMessage(), $e->getContext() 
      ) 
     ); 
    } 
    $this->render('related_template.html.twig'); 
} 

Я знаю, как перенаправить пользователя с прослушивателем, но я действительно хочу, чтобы пользователь приземлился на конкретный ответ действия, только с введенной вспышкой.

ответ

2

Вы можете создать исключение listener:

# app/config/services.yml 
services: 
    kernel.listener.your_listener_name: 
     class: AppBundle\EventListener\AcmeExceptionListener 
     arguments: [@router, @session] 
     tags: 
      - { name: kernel.event_listener, event: kernel.exception, method: onKernelException } 

Затем установите флэш-сообщение и перенаправить пользователя к действию вы хотите, что сделает его:

class AcmeExceptionListener 
{ 
    /** 
    * @var UrlGeneratorInterface 
    */ 
    private $router; 

    /** 
    * @var SessionInterface 
    */   
    private $session; 

    public function __construct(UrlGeneratorInterface $router, SessionInterface $session) 
    { 
     $this->router = $router; 
     $this->session = $session; 
    } 

    public function onKernelException(GetResponseForExceptionEvent $event) 
    { 
     $exception = $event->getException(); 

     if ($exception instanceof YourExceptionType) { 
      $this->session->getFlashBag()->add('error', $exception->getMessage()); 

      $event->setResponse(new RedirectResponse($this->router->generate('your_route')));  
     } 
    } 
} 

Будьте осторожны с этим, хотя : если при обработке исключений вы снова бросаете YourExceptionType, у вас будет бесконечный цикл перенаправления.

+0

Спасибо за ваш ответ, этот код прослушивания исключений интересен. Я, наконец, использовал черту, чтобы добавить ярлык try/catcher, чтобы я мог продолжить выполнение моих контроллеров (т. Е. Вернуть соответствующий конкретный ответ). Я собираюсь добавить свое решение здесь –

0

Я, наконец, использовал trait, чтобы продолжить выполнение моих контроллеров с помощью встроенной вспышки.

/** 
* Class ControllerTrait 
* @requirement The using class must be containerAware 
*/ 
trait ControllerTrait { 
    public function injectExceptionFlash(AbstractApplicationException $e) { 
     if (!isset($this->container)) { 
      throw new \Exception(sprintf('You must containerAware to use %s', 
       __TRAIT__ 
      )); 
     } 
     $flashBag = $this->container->get('session')->getFlashBag(); 
     $flashBag->add('error', 
      $this->container->get('translator')->trans(
       $e->getMessage(), $e->getContext() 
      ) 
     ); 
    } 

    public function tryFlash($lambda) { 
     try { 
      $lambda(); 
     } catch (AbstractApplicationException $e) { 
      $this->injectExceptionFlash($e); 
     } 
    } 
} 

Вот как я использую его из моих контроллеров

use ControllerTrait; 

public myControllerAction() 
    $this->tryFlash(function() (use $someParam) { 
     $someService->someFunction($someParam); 
    }); 
    $this->render('related_template.html.twig'); 
} 

tryFlash() ярлык с помощью lambda function, чтобы сделать попытку/поймать/флеш работы

Не стесняйтесь сказать мне если есть плохая практика где-то

Смежные вопросы