与未回答的问题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");
实际显示在底部,但是在ohter(语法错误)上它没有显示,即使它们似乎都被Symfony2捕获。进一步的测试显示die("test");
出现了,但是死了(“&gt;&gt;。$ exception-&gt; getStatusCode()。”&lt;&lt;“);没有。我假设这导致了第二次我没有看到的异常,就像AccessDeniedException没有这个函数调用而我必须使用instanceof
,但是有很多可能出现500错误的错误,所以如何区分错误是什么是其中之一吗?
进一步编辑:对于在底部打印“测试”的错误,我注意到当我执行$container->testError();
时,我没有得到“测试”,错误的底部,但是当我做return $container;
时,即使两个错误都是带有未定义变量的ContextErrorException。
答案 0 :(得分:0)
在Symfony有机会开始之前,你最常得到的500个错误。由于Symfony在这种情况下无法启动,因此无法处理错误。要调试此类情况,您应该查看Web服务器(apache,ngnix等)日志。
答案 1 :(得分:0)
我刚测试了500个例外,它似乎工作正常。我想你可能还有别的事情可以拦截这个例外吗?也许开始一个新项目再试一次。
我自己更喜欢订阅者界面:
class ExceptionListener extends ContainerAware implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(KernelEvents::EXCEPTION => array(
array('doException', 200),
));
}
public function doException(GetResponseForExceptionEvent $doEvent)
{
$exception = $doEvent->getException();
die('Exception caught ' . $exception->getStatusCode());
cerad_core__exception_listener:
class: Cerad\Bundle\CoreBundle\EventListener\ExceptionListener
tags:
- { name: kernel.event_subscriber }
请注意,您还可以配置记录器以发送电子邮件。可能会更容易。
http://symfony.com/doc/current/cookbook/logging/monolog_email.html
@Ferhad提出了一个很好的观点。一些(但不是全部)500错误基本上会使S2应用程序崩溃。但我假设您正在获取默认的S2异常消息。