首页 > 解决方案 > 捆绑特定的异常侦听器

问题描述

假设我有 3 个不同的捆绑包。

我正在为每个捆绑包添加事件侦听器。当 Bundle1 出现异常时,Bundle2 和 Bundle3 不应该监听。

我已经将它添加到每个捆绑事件侦听器中进行了测试,但是当 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);
}

我读到有可能只听控制器。但在那种情况下,控制器监听器也会监听异常吗?

标签: phpsymfonyoopsymfony4

解决方案


您需要做的是创建不同的异常“家族”,每个事件侦听器应根据其父级决定对异常采取行动或不采取行动。

例如,假设您在每个捆绑包上创建了一个抽象异常:

abstract class BundleOneException extends \Exception {}

(对于 BundleTwo 和 BundleThree 也是如此)。现在在每个捆绑包上,您抛出的每个异常都应该是这个异常的扩展。

然后在每个听众上你可以这样做:

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

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

    // otherwise, do your thing

}

所有侦听器都在侦听所有异常,但它们只会对适当的异常采取行动。

这是处理这种情况的最实际的方法。是的,您需要每个包在它们抛出的异常类型上保持一致;但是抛出通用异常不是很好的做法(正如这种情况所证明的那样)。


推荐阅读