(控制器)如何自定义错误页面

当symfony出现异常时,都会被Kernel类所捕获并最终转发到一个特殊的控制器TwigBundle:Exception:show来处理。这个控制器在核心的TwigBundle里,他来确定显示哪些错误模板,并且给相关异常设定状态码。

错误页面可以定义为两种不同的形式,这取决与你要更改的灵活度:
1.自定义不同错误页面的模板
2.替换默认的异常控制器 twig.controller.exception:showAction

默认ExceptionController

默认ExceptionController是否显示一个异常或错误页面,取决于是否这是kernel.debug。虽然异常页面会给我们排查问题提供很多有用信息,但是最终给用户显示的应该是错误页面,而不是异常页面。

在开发过程中测试错误页面
在开发过程中你要看到你的错误页面,你就不能设置kernel.debug为false。这是因为它会阻止symfony重新编译twig模板等,看不到异常页面。
这个第三方WebfactoryExceptionsBundle提供了一个特殊的测试控制器,它能够在kernel.debug设置为true的情况下,允许你显示任意的http状态的自定义错误页面。

重写错误模板

所有的错误模板都写在TwigBundle下。去重写这个模板,只需要遵守这个bundle的基本方法就可以了。更多方法请看 重写bundle模板
举例,我们现在就去重写一个默认的错误模板,那么需要在此路径下新建一个模板
app/Resources/TwigBundle/views/Exception/error.html.twig

你一定不能在你的错误页面使用is_granted(或者layout使用你的错误页面),因为路由运行在防火墙之前。如果路由器抛出异常(例如,当路由不匹配时)你使用is_granted将引发有一个异常。或者你能够通过这种方式{% if app.user and is_granted(‘…’) %}来使用is_granted。

如果你不熟悉Twig,不用担心。Twig是symfony中非常简单,强大和可选择的模板引擎。更多信息请查看  book文档(创建和使用模板)。

除了标准的html页面,symfony还提供很多其他格式的错误页面,例如JSON(error.json.twig),XML(error.xml.twig)甚至还有JavaScript(error.js.twig)。只需要在这个app/Resources/TwigBundle/views/Exception目录下创建同名文件就可以重写这些模板了。上面是用标准的方法重写这些在bundle里的模板。

 

自定义404页面和其他错误页面

你可以根据http的状态定制特定的模板。例如创建一个app/Resources/TwigBundle/views/Exception/error404.html.twig模板去显示一个不存在的404错误页。

symfony使用下面的算法去决定使用哪个模板:

  • 首次,判断给定的格式和状态码,并寻找一个模板(像:error404.json.twig);
  • 如果error404.json.twig不存在,他会去寻找给定的格式模板(例如:error.json.twig)
  • 如果error.json.twig也不存在,他会返回html模板(例如:error.html.twig)

要是去看所有的额默认错误模板,在TwigBundle的Resources/views/Exception目录下。在symfony标准版里就可以找到TwigBundle在vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle。有一个简单的方法,我们可以从TwigBundle里拷贝页面到app/Resources/TwigBundle/views/Exception目录下并修改它,让他成为一个自定义的错误页。

同样开发人员可以自定义这些友好的异常页面,例如可以创建模板exception.html.twig是为了标准的HTML页面异常显示和exception.json.twig是JOSN异常页面显示。

 

替换默认的异常控制器

如果你需要更多的灵活性,那只修改模板文件是不够的(例如你可能需要传入一些自己的变量到你的模板),那么你可以重写你的控制器去渲染自己的模板。

默认的异常控制器是注册为一个服务的

—— 实际的类是Symfony\Bundle\TwigBundle\Controller\ExceptionController

为此,创建一个新的控制器并且让他继承默认的symfony类

Symfony\Bundle\TwigBundle\Controller\ExceptionController

你可以有几种方法,把自定义的不同部分在错误页面里呈现,例如你可以覆盖整个showAction或者只是findTemplate方法让自己的模板渲染。

为了让symfony能够使用自己的异常控制器而不是默认的,设置app/config/config.yml的twig.exception_controller选项。

自定义的异常处理实际上比上面写的更强大。一个内部事件Kernel.exception是能够完全控制所有抛出的异常。详细内容可查看,kernel.exception Event

发表评论