【发布时间】:2014-03-06 12:40:23
【问题描述】:
与未回答的问题 Symfony 2.4: Why are 500 errors not caught by kernel.exception listener 完全相同。
我已经实现了一个自定义异常“处理程序”,它非常适用于 403 和 404 问题,但有 500 个错误(这是我真正想要处理的,因为我想在发生这种情况时从系统向自己发送电子邮件)不会触发我的自定义“处理程序”并继续表现得好像自定义“处理程序”不存在一样。代码比较简单:
从 app/config/config.yml 中提取:
services:
core.exceptlistener:
class: Pmb\LicensingBundle\Listener\ExceptionListener
arguments: ["@service_container", "@router"]
tags:
- { name: kernel.event_listener, event: kernel.exception, method: onKernelException, priority: 200 }
整个\Pmb\LicensingBundle\Listener\ExceptionListener.php:
<?php
namespace Pmb\LicensingBundle\Listener;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Bundle\TwigBundle\TwigEngine;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
class ExceptionListener
{
private $container;
private $router;
function __construct($container, $router)
{
$this->container = $container;
$this->router = $router;
}
public function onKernelException(GetResponseForExceptionEvent $event)
{
$exception = $event->getException();
die("test");
$request = $this->container->get('request');
$templating = $this->container->get('templating');
if ($exception instanceof \Symfony\Component\Security\Core\Exception\AccessDeniedException)
{
# If AJAX request, do show not error page.
if ($request->isXmlHttpRequest())
{
$response = new Response(json_encode(array('error' => 'Access Denied: Not logged in as administrator')));
}
else
{
return new RedirectResponse($this->router->generate('login'));
}
$event->setResponse($response);
}
elseif ($exception->getStatusCode() == 404)
{
# If AJAX request, do show not error page.
if ($request->isXmlHttpRequest())
{
$response = new Response(json_encode(array('error' => 'Requested route could not be found')));
}
else
{
$response = new Response($templating->render('PmbLicensingBundle:Exception:error404.html.twig', array(
'exception' => $exception
)));
}
$event->setResponse($response);
}
else
{
# TODO: Send Email
# If AJAX request, do not show error page.
if ($request->isXmlHttpRequest()) $response = new Response(json_encode(array('error' => 'Internal Server Error Encountered. Developer has been notified.')));
else
{
$response = new Response($templating->render('PmbLicensingBundle:Exception:error500.html.twig', array(
'exception' => $exception
)));
}
}
}
}
我将die("test") 放在那里以验证根本没有调用“处理程序”,这不仅仅是我的 if-else 逻辑的问题。如前所述,这对任何 404 或 403 错误都非常有效,但 500 错误完全忽略了这一点并以默认方式运行。我很确定这与监听器服务的注册有关,但我找不到任何解释如何使其正常工作的东西。
编辑:以下是未按预期处理的错误的屏幕截图。我注意到一个(未定义的变量)die("test"); 实际上显示在底部,但在另一个(语法错误)上它没有显示,即使它们似乎都被 Symfony2 捕获了。进一步的测试表明 die("test"); 出现了,但是 die(">> .$exception->getStatusCode()." instanceof,但是有很多可能的错误会出现500错误,那么如何区分错误是不是其中之一呢?
进一步编辑:关于在底部打印“测试”的错误,我注意到当我执行$container->testError(); 时,我没有得到底部的“测试”错误,但是当我执行return $container; 时,我会这样做,即使这两个错误都是带有未定义变量的 ContextErrorException。
【问题讨论】:
标签: symfony