Php 如何使用自定义错误500模板和EventListener在Symfony2上报告生产中的错误?
我想在自定义错误模板上报告我的错误消息。因此,我遵循了覆盖默认错误模板的步骤: 我的Php 如何使用自定义错误500模板和EventListener在Symfony2上报告生产中的错误?,php,templates,exception-handling,symfony,Php,Templates,Exception Handling,Symfony,我想在自定义错误模板上报告我的错误消息。因此,我遵循了覆盖默认错误模板的步骤: 我的error500.html.twig页面模板如下所示: <div class=" details"> <h3>Oops! Something went wrong.</h3> <p> We are fixing it! Please come back in a while.
error500.html.twig
页面模板如下所示:
<div class=" details">
<h3>Oops! Something went wrong.</h3>
<p> We are fixing it! Please come back in a while.
<br/> TEST</p>
<div class="alert alert-danger display-hide" {{message ? 'style="display: block;"'}}>
<button class="close" data-close="alert"></button>
<span>{{message ? message | trans}}</span>
</div>
<p>
<a href="{{path('homepage')}}" class="btn red btn-outline"> OK, take me to the homepage </a>
<br> </p>
</div>
我认为我只是缺少正确的方法来设置Symfony\Component\HttpFoundation\Response
的正确模板。实际上,我已经能够截获内核异常事件,但是我返回了一个没有任何模板的经典HTML错误页面
我正在使用PHP7和Symfony 2.8.4
编辑
我找到了通过状态代码截获异常类型的正确方法:
public function onKernelException(GetResponseForExceptionEvent $event)
{
$exception = $event->getException();
$statusCode = $exception->getStatusCode();
$message = sprintf(
'ERROR: %s with code: %s',
$exception->getMessage(),
$exception->getCode()
);
switch ($statusCode) {
case 404:
$errorTemplate = 'TwigBundle:Exception:error404.html.twig';
break;
case 403:
$errorTemplate = 'TwigBundle:Exception:error403.html.twig';
break;
default:
$errorTemplate = 'TwigBundle:Exception:error500.html.twig';
break;
}
$response = $this->templating->renderResponse(
$errorTemplate,
['message' => $message]
);
// HttpExceptionInterface is a special type of exception that
// holds status code and header details
if ($exception instanceof HttpExceptionInterface) {
$response->setStatusCode($exception->getStatusCode());
$response->headers->replace($exception->getHeaders());
} else {
$response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
}
$event->setResponse($response);
}
services:
app.exception_listener:
class: AppBundle\EventListener\ExceptionListener
arguments: [ '@templating' ] # Here
tags:
- { name: kernel.event_listener, event: kernel.exception }
然后,在ExceptionListener类中添加以下内容:
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
// ...
class ExceptionListener
{
/** @var EngineInterface */
private $templating;
/**
* @param EngineInterface $templating
*/
public function __construct(EngineInterface $templating)
{
$this->templating = $templating;
}
// ...
}
然后,使用它渲染视图:
public function onKernelException(GetResponseForExceptionEvent $event)
{
// ...
$response = $this->templating->renderResponse(
'TwigBundle:Exception:error_500.html.twig',
['message' => $message]
);
$event->setResponse($response);
}
注意应该正确使用自定义(重写)模板,否则请使用
'TwigBundle/Exception/error\u 500.html.twig'
作为$this->templating->renderResponse()
的第一个参数,而不是'TwigBundle:Exception:error\u 500.html.twig'
根据当前环境切换使用的模板
从TwigBundle(您希望在开发中使用)复制原始模板,并将其内容复制到新的app/Resources/TwigBundle/Exception/error\u 500_dev.html.twig
中
在error\u 500\u prod.html.twig
中重命名自定义模板
将环境作为参数注入服务:
app.exception_listener:
# ...
arguments: [ '@templating', '%kernel.environment%' ]
在构造函数中将其设置为ExceptionListener::$env,就像模板设置一样
然后,使用它渲染好的模板:
$response = $this->renderResponse(
sprintf('TwigBundle:Exception:error_500_%s', $this->env),
// ...
);
它起作用了!但是我想要
dev
环境的默认错误模板。在dev中是否可以排除这种行为?我在回答的末尾添加了一个替代选项。这不是一个“固定”的解决方案,您应该根据您的需要调整它。我观察到另一个错误,我认为这可能是由这种方法引起的:当路由匹配404时,它调用error500模板,并返回错误:生成URL时缺少一些必需的参数(“语言环境”)。我无法找出解决问题的方法……我想我已经找到了刚才报告的问题的原因。但我还是需要显示错误404页面。有什么线索吗?我已经在问题编辑部分报告了我的答案。
app.exception_listener:
# ...
arguments: [ '@templating', '%kernel.environment%' ]
$response = $this->renderResponse(
sprintf('TwigBundle:Exception:error_500_%s', $this->env),
// ...
);