Symfony 2.5 - 我无法捕获PDOException

时间:2014-11-26 10:58:07

标签: php symfony pdo exception-handling

我正处于基于symfony 2.5构建新项目的最后阶段,我认为拥有自定义错误页面会很不错。我创建了自己的Exception Listener,请参阅下面的代码:

以下是服务声明:

kernel.listener.core_exception_listener:
    class: MyCompany\CoreBundle\Listener\ExceptionListener
    arguments: [@templating, @kernel]
    tags:
        - { name: kernel.event_listener, event: kernel.exception, method: onKernelException }

这是实际的PHP类:

<?php
namespace MyCompany\CoreBundle\Listener;

use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;

use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;

use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class ExceptionListener
{
    protected $templating;
    protected $kernel;

    public function __construct(EngineInterface $templating, $kernel)
    {
        $this->templating = $templating;
        $this->kernel = $kernel;
    }

    public function onKernelException(GetResponseForExceptionEvent $event)
    {
        // provide the better way to display a enhanced error page only in prod environment, if you want
        if ('prod' == $this->kernel->getEnvironment()) {
            // exception object
            $exception = $event->getException();

            // new Response object
            $response = new Response();

            if($exception instanceof NotFoundHttpException) {
                $template = 'CoreBundle:Exception:404.html.php';
            } else {
                $template = 'CoreBundle:Exception:exception.html.php';
            }

            $response->setContent(
                // create you custom template AcmeFooBundle:Exception:exception.html.twig
                $this->templating->render(
                    $template,
                    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);
        }
    }
}

这适用于404页面,但不幸的是它不适用于PDOExceptions。作为一个例子,我停止了我的mysql服务器并刷新了页面,而不是我的自定义错误页面,我实际上获得了异常跟踪日志和HTTP响应代码200(如wtf .. :))

有什么建议吗? 感谢

P.S。:创建文件app / Resources / TwigBundle / views / Exception / error.html.twig绝对没有效果..

P.P.S。:在服务声明中添加优先级属性也没有效果。

2 个答案:

答案 0 :(得分:1)

要捕获PDOException,您必须将其命名为 将其添加为use语句或在调用时添加前导\。 例如;

try {
   // your code
} catch (\PDOException $pdo_ex) {
   die("Oops, ".$pdo_ex->getMessage());
}

答案 1 :(得分:0)

这是代码帮我解决http://www.inanzzz.com/index.php/post/nm7o/catching-orm-dbal-and-pdo-exceptions-in-symfony

的检查错误
   $em = $this->getDoctrine()->getEntityManager();

    try {
        $em->persist($country);
        $em->flush();
        $message = 'Done';
    } catch (DBALException $e) {
        $message = sprintf('DBALException [%i]: %s', $e->getCode(), $e->getMessage());
    } catch (PDOException $e) {
        $message = sprintf('PDOException [%i]: %s', $e->getCode(), $e->getMessage());
    } catch (ORMException $e) {
        $message = sprintf('ORMException [%i]: %s', $e->getCode(), $e->getMessage());
    } catch (Exception $e) {
        $message = sprintf('Exception [%i]: %s', $e->getCode(), $e->getMessage());
    }

    echo $message;
}

}