[英]How to report error in production on Symfony2 with a custom ERROR 500 template and an EventListener?
我想報告有關自定義錯誤500模板的錯誤消息。 因此,我遵循了有關覆蓋默認錯誤模板的官方symfony教程 :
app/
└─ Resources/
└─ TwigBundle/
└─ views/
└─ Exception/
├─ error404.html.twig
├─ error403.html.twig
├─ error.html.twig # All other HTML errors (including 500)
├─ error404.json.twig
├─ error403.json.twig
└─ error.json.twig # All other JSON errors (including 500)
我的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>
現在,我想通過使用偵聽onKernelException的ExceptionListener來編寫特定的message
參數,如Symfony Cookbook所述 :
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
class ExceptionListener
{
public function onKernelException(GetResponseForExceptionEvent $event)
{
// You get the exception object from the received event
$exception = $event->getException();
$message = sprintf(
'My Error says: %s with code: %s',
$exception->getMessage(),
$exception->getCode()
);
// Customize your response object to display the exception details
$response = new Response();
$response->setContent($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);
}
// Send the modified response object to the event
$event->setResponse($response);
}
}
我認為我只是缺少設置Symfony\\Component\\HttpFoundation\\Response
的正確模板的正確方法。 實際上,我已經能夠攔截內核異常事件,但是我返回的是沒有任何模板的經典HTML錯誤頁面。
我正在使用PHP 7和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_500.html.twig'
用作$this->templating->renderResponse()
的第一個參數,而不是'TwigBundle:Exception:error_500.html.twig'
。
根據當前環境切換使用的模板
從TwigBundle中復制原始模板(您要在dev中使用),然后將其內容復制到新的app/Resources/TwigBundle/Exception/error_500_dev.html.twig
。
在error_500_prod.html.twig
重命名您的自定義模板。
將環境作為服務的參數:
app.exception_listener:
# ...
arguments: [ '@templating', '%kernel.environment%' ]
像在模板中一樣,在構造函數中將其設置為ExceptionListener :: $ env。
然后,使用它來渲染好的模板:
$response = $this->renderResponse(
sprintf('TwigBundle:Exception:error_500_%s', $this->env),
// ...
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.