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

时间:2019-03-26 23:01:44

标签: php symfony exception symfony4 php-7.2

我正在Symfony 4中构建一个自定义异常控制器,以覆盖Twig捆绑包中包含的ExceptionController类。

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

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

我使用自定义异常控制器的原因是因为我需要将一些附加变量传递给自定义BaseController类所提供的模板。

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

  

TwigBundle用作kernel.exception事件的侦听器的ExceptionListener类创建了将分派到您的控制器的请求。另外,您的控制器将传递两个参数:

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));
    }
} 

1 个答案:

答案 0 :(得分:1)

您正在从文档页面开始链接,在Overriding the default template章的开头,文档实际上将您交叉链接到类\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));
    }
}