如何在 symfony 5 中设置自定义 ErrorRenderer?

mys*_*elf 5 exception symfony custom-error-handling symfony5

问题:我尝试在 Symfony 5 上注册 CustomErrorRenderer 来呈现我的 CustomException,但 TwigErrorRenderer 始终被调用。我认为自定义渲染器可能是首选?

CustomErrorRenderer.php:

namespace App\ErrorRenderer;
use Symfony\Component\ErrorHandler\Exception\FlattenException;
use Symfony\Component\ErrorHandler\ErrorRenderer\ErrorRendererInterface;


class CustomErrorRenderer implements ErrorRendererInterface
{
    public function render(\Throwable $exception): FlattenException
    {
        dd('CustomErrorRenderer.render() called');
        // TODO check if CustomException, else refer to preset renderer...

    }
}
Run Code Online (Sandbox Code Playgroud)

服务.yaml:

services:
    App\ErrorRenderer\CustomErrorRenderer:
        tags: ['error_renderer.renderer']
        # also tried: ['error_renderer.renderer', 'error_renderer.html','error_handler.error_renderer' , 'error_handler.error_renderer.html']
Run Code Online (Sandbox Code Playgroud)

这有什么问题吗?

背景:我有一个 Web 应用程序,想要单独处理与我的内部业务逻辑相关的异常。例如,用户想要预订资源但当前不可用。虽然当前的错误/异常由 TwigErrorRenderer (或默认的 HtmlErrorRenderer )处理,但我想添加自己的渲染器(理想情况下只是扩展 TwigErrorRenderer ,以便我可以使用一些特定的、自定义的树枝模板)。这样,我的目标是拥有更好的 UI,例如,在显示 Web 应用程序的菜单的同时呈现我的自定义异常。由于我的异常与数据的访问方式(例如 http)无关,因此我不想使用 HttpExceptions 及其状态代码。

so_*_*so_ 0

这并不是特别容易弄清楚。

我将 复制vendor/symfony/twig-bridge/ErrorRenderer/TwigErrorRenderer.php到我的应用程序中src\CustomerErrorRenderer.php

然后覆盖error_rendererin services.yaml

services:
    error_renderer:
        class: App\CustomErrorRenderer
        arguments: ['@twig', '@error_handler.error_renderer.html','%kernel.debug%']
Run Code Online (Sandbox Code Playgroud)

当然,当我尝试使用/_error/404例如测试时,这并不完全是他们在代码中调用的方式。

他们实际上使用的参数更像是:

  error_renderer:
    class: App\Twig\CustomErrorRenderer
    arguments:
      - '@twig'
      - '@error_handler.error_renderer.html'
      - !service
        factory: [ 'Symfony\Component\ErrorHandler\ErrorRenderer\HtmlErrorRenderer', 'getAndCleanOutputBuffer' ]
        arguments: ['@request_stack']
Run Code Online (Sandbox Code Playgroud)