未触发 Symfony 异常订阅者

Symfony Exception Subscriber not triggered

我需要格式化错误信息并以JSON格式输出。

我有以下事件订阅者:


namespace App\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\KernelEvents;

final class ExceptionSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [KernelEvents::EXCEPTION => 'onKernelException'];
    }

    public function onKernelException(ExceptionEvent $event) {/*..*/}
}

并遵循 ./config/services.yaml

中的配置
services:
    _defaults:
        autowire: true
        autoconfigure: true

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

此事件订阅者正在工作,例如控制器抛出错误。

但是如果我遇到其他错误,例如错误的 DI 注入

class FooBar {
    public __constructor(NonExistingService $service) {/*..*/}
}

然后输出仍然是 Html 格式和 Symfony 错误页面。


如何使 Symfony 捕获的任何错误通过我的 class 转换为 JSON?

不确定这是否是您所指的内容,但请确保您正确设置了响应:


    public function onKernelException(ExceptionEvent $event): void
    {
        $exception = $event->getThrowable();

        $response = new JsonResponse(
            ['error'],
            Response::HTTP_INTERNAL_SERVER_ERROR,
            [
                'Content-Type' => 'application/vnd.api+json',
            ]
        );

        $event->setResponse($response);
    }

您可以覆盖配置中的默认错误控制器。

在此处查看文档:https://symfony.com/doc/current/controller/error_pages.html#overriding-the-default-errorcontroller

我发现这里出了什么问题。

问题是,如果你有,例如配置错误,您的活动还没有连接起来。

在我的代码中我有这个:

// index.php

if ($_SERVER['APP_DEBUG']) {
    umask(0000);

    $errorHandler = Debug::enable();
}

$kernel = new Kernel();
/* .. */

这个 Debug::enable() 实际上设置了错误处理程序(没有它,启动时只有 PHP 默认错误处理程序)。

我用自己的 class 扩展了 Debug:


namespace App\Error;

use Symfony\Component\ErrorHandler\BufferingLogger;
use Symfony\Component\ErrorHandler\Debug as SymfonyDebug;
use Symfony\Component\ErrorHandler\ErrorHandler;

class Debug extends SymfonyDebug
{
    public static function enable(): ErrorHandler
    {
        if ($_SERVER['APP_DEBUG']) {
            umask(0000);

            $errorHandler = parent::enable();
        }

        return self::setDefaultErrorHandler($errorHandler ?? null);
    }

    private static function setDefaultErrorHandler(?ErrorHandler $errorHandler): ErrorHandler
    {
        $errorHandler ??= ErrorHandler::register(new ErrorHandler(new BufferingLogger(), true));

        $errorHandler->setExceptionHandler([ExceptionHandler::class, 'renderException']);

        return $errorHandler;
    }
}


现在所有错误都通过我的 App\Error\ExceptionHandler,我可以将其输出为 JsonResponse