Symfony 2.4: Dlaczego 500 błędów nie jest wychwytywanych przez nasłuchiwanie kernel.exception
Próbuję utworzyć detektor do słuchania 403, 404 i 500 wyjątków. Działa to dobrze dla wyjątków 403 i 404, ale nie dla 500 wyjątków. Dla 500 wyjątków (lub wyjątków, które zostaną zwrócone jako 500 błędów dla klienta) metoda onKernelException nigdy nie jest wywoływana. Wydaje się, że jest taki sam w moim obecnym projekcie Symfony i kiedy kod jest dodawany do czystej instalacji Symfony 2.4.1.
Następnie wprowadzam błąd 500, wykonując nieistniejącą funkcję.
W środowisku programistycznym otrzymuję stronę wygenerowaną przez Symfony z napisem „Ups, wygląda na to, że coś poszło nie tak”. a następnie wyświetla informacje o rzuconym „UndefinedFunctionException” wraz z kodem stanu 500.
W środowisku produkcyjnym otrzymuję pustą stronę wraz z kodem statusu 500. W dzienniku błędów prod.log pojawia się błąd „Błąd krytyczny PHP: wywołanie funkcji niezdefiniowanej” ze śledzeniem stosu.
Ponieważ Symfony oczywiście łapie ten błąd, dlaczego nie mogę złapać odpowiedniego wyjątku za pomocą detektora kernel.exception?
Klasa, której używam to:
<?php
namespace SystemBundle\Listener;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
/**
* This exception listener will listen to 500, 404, and 403 errors and render a corresponding view
*
* @SuppressWarnings("static")
* @SuppressWarnings("else")
*/
class ExceptionListener
{
protected $templating;
protected $kernel;
public function __construct(EngineInterface $templating, $kernel)
{
$this->templating = $templating;
$this->kernel = $kernel;
}
public function onKernelException(GetResponseForExceptionEvent $event)
{
$container = $this->kernel->getContainer();
// Exception object
$exception = $event->getException();
// Create Response object
$response = new Response();
// Get view name
$viewName = $container->getParameter('theme') . ':Exception:exception.html.twig';
if (!$this->templating->exists($viewName)) {
$viewName = 'AckebrinkChallengerSystemBundle:Exception:exception.html.twig';
}
// Set response content
$response->setContent($this->templating->render($viewName, array('exception' => $exception)));
// 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(500);
}
// set the new $response object to the $event
$event->setResponse($response);
}
}
a konfiguracja usługi, której używam to:
services:
kernel.listener.system_exception_listener:
class: SystemBundle\Listener\ExceptionListener
arguments:
- @templating
- @kernel
tags:
- { name: kernel.event_listener, event: kernel.exception, method: onKernelException }