Symfony2:如何使用异常侦听器

时间:2015-05-12 13:27:13

标签: php symfony exception pdo doctrine-orm

在我的symfony2应用程序中,我有一个异常监听器,它会在发生错误时记录这些错误。

不幸的是,symfony2异常监听器似乎无法捕获PDO异常。

我的代码:

exception_listener:
    class: %exception_listener.class%
    arguments: [@router, @session, @security.token_storage, @email_manager, @doctrine, "@=service('kernel').getEnvironment()", @security.authorization_checker]
    tags:
        - { name: kernel.event_listener, event: kernel.exception, method: onKernelException, priority: 250 }

如何在不使用try / catch代码的情况下解决这个问题,即让侦听器捕获此错误?

非常感谢

编辑:添加了异常监听器代码,但它甚至没有调用(如果我在onKernelException的第一行放置vardump,则没有转储):

<?php

namespace AppBundle\EventListener;

use AppBundle\Application\Core\EmailManager;
use AppBundle\Application\Core\JournalManager;
use AppBundle\Entity\User\User;
use AppBundle\Security\Voter\SubscriptionVoter;
use Doctrine\Bundle\DoctrineBundle\Registry;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;


class ExceptionListener
{
    /**
     * @var Router
     */
    private $router;

    /**
     * @var Session
     */
    private $session;

    /**
     * @var TokenStorage
     */
    private $tokenStorage;

    /**
     * @var EmailManager
     */
    private $emailManager;

    /**
     * @var null
     */
    private $environment;

    /**
     * @var AuthorizationChecker
     */
    private $authorizationChecker;
    /**
     * @var Registry
     */
    private $doctrine;

    public function __construct(Router $router, Session $session, TokenStorage $tokenStorage, EmailManager $emailManager, Registry $doctrine ,$environment=null, AuthorizationChecker $authorizationChecker)
    {
        $this->router = $router;
        $this->session = $session;
        $this->tokenStorage = $tokenStorage;
        $this->emailManager = $emailManager;
        $this->environment = $environment;
        $this->authorizationChecker = $authorizationChecker;
        $this->doctrine = $doctrine;
    }

    public function onKernelException(GetResponseForExceptionEvent $event)
    {
        /** @var $exception */
        $exception = $event->getException();
        $request = $event->getRequest();
        $referer = $request->headers->get('referer');

        $manager = $this->doctrine->getManager('logging');
        $journalManager = new JournalManager($manager);


//        try {
            $currentUrl = $this->generateUrl($request);

            if($exception->getCode() == 403)
            {
                if ($this->authorizationChecker->isGranted(SubscriptionVoter::HAS_SUBSCRIPTION) && !$this->authorizationChecker->isGranted(SubscriptionVoter::SUBSCRIPTION_VALID))
                {
                    $this->session->getFlashBag()->add('warning',"La page précédente n'est pas accessible avec ce portfolio car le paiement n'est pas à jour. Vous devez actualiser votre paiement.");
                    $response = new RedirectResponse($this->router->generate('renew_subscription'));
                }
                else
                {
                    $this->session->getFlashBag()->add('warning',"La page précédente n'est pas accessible avec vos droits d'accès et vous avez été redirigé vers l'accueil du site. Avez-vous sélectionné le bon portfolio ?");
                    $response = new RedirectResponse($this->router->generate('home'));
                }

                $event->setResponse($response);
            }
            elseif ($exception->getMessage() == "Couldn't connect to host, Elasticsearch down?" || $exception->getCode() == 52)
            {
                $this->session->getFlashBag()->add('warning', "La service de recherche du site a arrêté de fonctionner. Renouvellez votre dernière action si celle si n'a pas été suivie d'effet d'ici 2 minutes.");
                $event->setResponse(new RedirectResponse($request->headers->get('referer') ?: $this->router->generate('home')));
            }
            elseif (
                !($exception->getCode() == 404 && !$referer) &&
                !(strstr($exception->getMessage(), 'object not found') && !$referer) &&
                !in_array($this->environment, array('dev', 'test')) &&
                $this->tokenStorage->getToken() &&
                !$journalManager->errorExists($exception, $currentUrl, 1)
            )
            {
                $user = is_object($this->tokenStorage->getToken()) ? $this->tokenStorage->getToken()->getUser() : null;
                $user = $user instanceOf User ? $user : null;
                $code = $exception->getCode();

                $this->emailManager->sendEmail(
                    'error@foodmeup.net',
                    'foodmeup@foodmeup.net',
                    ':Core/Email:error.html.twig',
                    "Une erreur $code s'est produite sur le site",
                    array(
                        'date' => new \DateTime(),
                        'user' => $user,
                        'exception' => $exception,
                        'referer' => $request->headers->get('referer'),
                        'current' => $this->generateUrl($request),
                        'user_agent' => $_SERVER['HTTP_USER_AGENT']
                    )
                );

//                try {
                    $journalManager->addErrorLog($exception, $currentUrl);
//                } catch (\Exception $e)
//                {
//
//                }
            }
//        } catch (\Exception $e)
//        {
//            $event->setResponse(new RedirectResponse($this->router->generate('home')));
//        }

    }

    public function generateUrl(Request $request = null)
    {
        try {
            $route = $this->router->generate($request->get('_route'),$request->attributes->get('_route_params'));
        }
        catch (\Exception $e)
        {
            $route = '';
        }

        return $request && $route ?  $request->server->get('SERVER_NAME') . $route : null;
    }
}

0 个答案:

没有答案