Symfony 4 中的自定义异常控制器

Custom Exception Controller in Symfony 4

我正在 Symfony 4 中构建自定义异常控制器以覆盖 Twig 包中包含的 ExceptionController class。

我正在按照 Symfony documentation for customizing error pages 执行此操作。

# config/packages/twig.yaml
twig:
    exception_controller: App\Controller\Error::handleException

我使用自定义异常控制器的原因是因为我需要将一些额外的变量传递给自定义 BaseController class.

提供的模板

Symfony 文档提到了以下关于使用自定义控制器的内容:

The ExceptionListener class used by the TwigBundle as a listener of the kernel.exception event creates the request that will be dispatched to your controller. In addition, your controller will be passed two parameters:

exception
    A FlattenException instance created from the exception being handled.

logger
    A DebugLoggerInterface instance which may be null in some circumstances. 

我需要 FlattenException 服务来确定错误代码,但文档中并不清楚这些参数是如何传递给自定义异常控制器的。

这是我的自定义异常控制器代码:

namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Debug\Exception\FlattenException;

class Error extends BaseController {

    protected $debug, // this is passed as a parameter from services.yaml
              $code;  // 404, 500, etc.

    public function __construct(BaseController $Base, bool $debug) {

        $this->debug = $debug;

        $this->data = $Base->data;

        // I'm instantiating this class explicitly here, but have tried autowiring and other variations that all give an error.
        $exception = new FlattenException();

        $this->code = $exception->getStatusCode(); // empty

    }

    public function handleException(){

        $template = 'error' . $this->code . '.html.twig';
        return new Response($this->renderView($template, $this->data));
    }
} 

您正在 link 阅读文档页面,在本章的最开始 Overriding the default template 文档实际上 link 您进入 class \Symfony\Bundle\TwigBundle\Controller\ExceptionController,这将向您展示如何使用它。

所以根据 Symfony 自己的 ExceptionControllerFlattenException 实际上是动作 showAction:

的参数
<?php

namespace App\Controller;

use Symfony\Component\Debug\Exception\FlattenException;
use Symfony\Component\HttpFoundation\Request;    
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;

class Error extends BaseController {

    protected $debug; // this is passed as a parameter from services.yaml
    protected $code;  // 404, 500, etc.
    protected $data;

    public function __construct(BaseController $base, bool $debug) {

        $this->debug = $debug;

        $this->data = $base->data;

    }

    public function showAction(Request $request, FlattenException $exception, DebugLoggerInterface $logger = null) {
        // dd($exception); // uncomment me to see the exception

        $template = 'error' . $exception-> getStatusCode() . '.html.twig';
        return new Response($this->renderView($template, $this->data));
    }
}