如何使用 Symfony 4 中的事件处理异常?

How to handle exceptions using events in Symfony 4?

现在我正在尝试捕获这样的异常事件:

try {
    echo 1 / 0;
} catch (\Exception $e){
    $subs = new ExceptionSubscriber();
    $this->dispatcher->addSubscriber($subs);
};

我定义了如下所示的 ExceptionSubscriber:

class ExceptionSubscriber implements EventSubscriberInterface
{

    public static function getSubscribedEvents()
    {
        return [
            KernelEvents::EXCEPTION => [
                ['processException', 10],
                ['exception', -10],
            ],
        ];
    }

    public function exception(ExceptionEvent $event)
    {
        echo 'test321';
    }

    public function processException(ExceptionEvent $event)
    {
        echo 'test123';
    }
}

这是我的 services.yaml

App\EventSubscriber\ExceptionSubscriber:
    tags:
        - { name: kernel.event_subscriber, event: kernel.exception }

我知道我捕获的常规 PHP 异常不是内核异常事件之一,在那种情况下我必须创建自定义异常事件,对吗?

我使用 EventSubscriber 发送事件的方式很好,而不是监听器

我是否必须分派这些事件,或者它们以某种神奇的方式传递给订阅者?

控制器中未捕获的异常被 symfony 捕获,然后构建并调度内核异常事件。
实际上你没有捕捉到任何异常,你正在订阅一个事件。 Symfony 捕获它们并且您收到一个带有方法 getException.
的事件 您可以在此处找到更多信息:Symfony: How to Customize Error Pages

当抛出 Exception(但未处理)时,HttpKernel 会捕获它并调度 kernel.exception 事件。

但在您的示例中,这永远不会发生,因为您自己正在捕获异常。并试图在那里创建一个订阅者,这没有多大意义;如果有的话,你会派遣一个事件。但是不需要调度新事件,因为框架已经调度了 kernel.exception 事件。

如果你想捕捉那个事件,你需要创建你自己的事件监听器。一个基本的例子:

class ExceptionListener
{
    public function onKernelException(ExceptionEvent $event)
    {
        $exception = $event->getException();

        // inspect the exception
        // do whatever else you want, logging, modify the response, etc, etc
    }
}

您需要配置此 class 以实际监听这些事件:

services:
    App\EventListener\ExceptionListener:
        tags:
            - { name: kernel.event_listener, event: kernel.exception }

无事可做。任何未捕获的异常都将通过这里。无需创建特定的 try/catch 块(尽管它们在一般情况下是个好主意,因为处理您自己的异常通常是一件好事)。

这些都在文档中的这些地方进行了解释,其中包括: