Прослушиватель определенных исключений - PullRequest
0 голосов
/ 18 февраля 2019

Допустим, у меня есть 3 разных пакета.

Я добавляю к слушателям событий каждый пакет.Когда в Bundle1 есть какое-либо исключение, Bundle2 и Bundle3 не должны его прослушивать.

Я проверил его добавление в каждый пакет событий EventListener, но когда в Bundle2 есть какая-либо ошибка, Bundle1 будет прослушивать, пытаясь обработать его.

Как справиться с этой ситуацией?

если нужен какой-либо код, то вот мой service.yaml в комплекте:

kernel.listener.test1bundle.exceptionlistener:
    class: App\test1bundle\EventListener\ExceptionListener
    tags:
        - { name: kernel.event_listener, event: kernel.exception}

и вот мой слушатель исключений:

public function onKernelException(GetResponseForExceptionEvent $event)
{
    // You get the exception object from the received event
    $exception = $event->getException();
    $message = [ 
        "errors" => [
            [
                "title" => "Internal error in test1 bundle",
                "detail" => $exception->getMessage()
            ]
        ]
    ];

    $response = new JsonResponse();
    $response->setData($message);

    $response->headers->set('Content-Type', 'application/problem+json');

    $event->setResponse($response);
}

я читал, что этоможно просто послушать контроллер.Но в этом случае прослушиватель контроллера будет также прослушивать исключения?

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Шина приемника событий является общей для всех пакетов в вашем приложении, поскольку все они создаются для определенного AppKernel.У вас есть несколько вариантов здесь:

  1. Разные ядра обрабатывают разные части вашего приложения (что означает, что вам придется направлять запросы к ним в вашем public/index.php фронт-контроллере), и добавьтеОтдельные слушатели как службы там.Это может быть довольно громоздким, поскольку в общем случае вам придется иметь дело не с одним приложением, а с несколькими.

  2. Если вы знаете, какие конкретные исключения вы хотите отловить в своемСлушатели, вы можете создать подклассы в каждом из ваших пакетов и продолжить работу в ExceptionListener s, если класс соответствует, , как @yivi предлагает в этом ответе .

  3. Вы также можете захватить трассировки стека исключений и проанализировать те, которые используют Exception::getTrace и некоторое итеративное копание, чтобы увидеть, было ли исключение, пойманное в вашем слушателе, действительно выброшено в конкретный файл, возможно, посмотрев натам есть поле file.

Но в целом, мне нужно что-то подобное, похоже на проблему с принципом разделения интересов в коде вашего приложения.Похоже, вы рассматриваете пакеты как отдельные приложения, но, насколько я знаю, это не тот способ декомпозиции, который предназначен для пакетов.Лучшие практики Symfony теперь предлагают иметь только AppBundle, но даже если вы хотите добавить больше пакетов, тем не менее, причина для этого заключается в разделении вашего кода по доменам, что автоматически приведет к тому, что исключения в каждом из пакетов будут иметь подклассовые исключения.

0 голосов
/ 18 февраля 2019

Что вам нужно сделать, это создать разные «семейства» исключений, и каждый слушатель события должен решить, действовать или не действовать на исключение в зависимости от его происхождения.

Например, скажем, что на каждом изваши пакеты вы создаете абстрактное исключение:

abstract class BundleOneException extends \Exception {}

(и то же самое для BundleTwo и BundleThree).Теперь в каждом пакете каждое выдаваемое исключение должно быть одно расширенным из этого.

Тогда для каждого слушателя вы можете сделать:

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

    if (!$exception instanceof BundleOneException) {
        return;
    }

    // otherwise, do your thing

}

Все слушатели слушают все исключения, но онибудет действовать только на соответствующих исключениях.

Это наиболее практичный способ разрешения ситуации.Да, вам нужно, чтобы каждый пакет соответствовал типу создаваемых исключений;но генерирование исключений общего характера не является большой практикой (как демонстрируется подобной ситуацией).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...