簡體   English   中英

如何使用自定義ERROR 500模板和EventListener報告Symfony2生產中的錯誤?

[英]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 7Symfony 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM