I'm trying to create a listener for listening 403, 404, and 500 exceptions. This works fine for 403 and 404 exceptions but not for 500 exceptions. For 500 exceptions (or exceptions that will be returned as 500 errors for the client) the method onKernelException is never called. It appears to be the same in my current Symfony project and when the code is added to a clean Symfony 2.4.1 install.
I then introduce a 500 error by executing a non-existent function.
In the development environment I get a Symfony generated page saying "Whoops, looks like something went wrong." and then views information about the thrown "UndefinedFunctionException" along with the 500 status code.
In the production environment I get an empty page along with the 500 status code. In the error log prod.log I get a "PHP Fatal error: Call to undefined function" error with a stack trace.
Since Symfony obviously catches this error, why can I not catch the corresponding exception with a kernel.exception listener?
The class I'm using is:
<?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);
}
}
and the service configuration I use is:
services:
kernel.listener.system_exception_listener:
class: SystemBundle\Listener\ExceptionListener
arguments:
- @templating
- @kernel
tags:
- { name: kernel.event_listener, event: kernel.exception, method: onKernelException }
First of all, ensure you cleared the Prod cache.
Second, see if something in the web server is catching errors for you, ie fastcgi_intercept_errors in Nginx, but this is unlikely to happen.
Third, try throwing an exception rather than calling a non-declared function.
Fourth, try to $event->setResponse as early as possible in the exception listener to ensure there's no error in the handler itself.
Other than that, I have no idea. The code seems to be Ok. Have you tried with XDebug to see how the code flows?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With