vendor/sentry/sentry-symfony/src/EventListener/ExceptionListener.php line 132

Open in your IDE?
  1. <?php
  2. namespace Sentry\SentryBundle\EventListener;
  3. use Sentry\SentryBundle\Event\SentryUserContextEvent;
  4. use Sentry\SentryBundle\SentrySymfonyEvents;
  5. use Symfony\Component\Console\Event\ConsoleCommandEvent;
  6. use Symfony\Component\Console\Event\ConsoleExceptionEvent;
  7. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  8. use Symfony\Component\HttpFoundation\Request;
  9. use Symfony\Component\HttpFoundation\RequestStack;
  10. use Symfony\Component\HttpKernel\Event\GetResponseEvent;
  11. use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
  12. use Symfony\Component\HttpKernel\HttpKernelInterface;
  13. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  14. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  15. use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter;
  16. use Symfony\Component\Security\Core\User\UserInterface;
  17. /**
  18.  * Class ExceptionListener
  19.  * @package Sentry\SentryBundle\EventListener
  20.  */
  21. class ExceptionListener implements SentryExceptionListenerInterface
  22. {
  23.     /** @var TokenStorageInterface|null */
  24.     private $tokenStorage;
  25.     /** @var AuthorizationCheckerInterface|null */
  26.     private $authorizationChecker;
  27.     /** @var \Raven_Client */
  28.     protected $client;
  29.     /** @var EventDispatcherInterface */
  30.     protected $eventDispatcher;
  31.     /** @var RequestStack */
  32.     private $requestStack;
  33.     /** @var string[] */
  34.     protected $skipCapture;
  35.     /**
  36.      * ExceptionListener constructor.
  37.      * @param \Raven_Client $client
  38.      * @param EventDispatcherInterface $dispatcher
  39.      * @param array $skipCapture
  40.      * @param TokenStorageInterface|null $tokenStorage
  41.      * @param AuthorizationCheckerInterface|null $authorizationChecker
  42.      */
  43.     public function __construct(
  44.         \Raven_Client $client,
  45.         EventDispatcherInterface $dispatcher,
  46.         RequestStack $requestStack,
  47.         array $skipCapture,
  48.         TokenStorageInterface $tokenStorage null,
  49.         AuthorizationCheckerInterface $authorizationChecker null
  50.     ) {
  51.         $this->client $client;
  52.         $this->eventDispatcher $dispatcher;
  53.         $this->requestStack $requestStack;
  54.         $this->skipCapture $skipCapture;
  55.         $this->tokenStorage $tokenStorage;
  56.         $this->authorizationChecker $authorizationChecker;
  57.     }
  58.     /**
  59.      * @param \Raven_Client $client
  60.      */
  61.     public function setClient(\Raven_Client $client)
  62.     {
  63.         $this->client $client;
  64.     }
  65.     /**
  66.      * Set the username from the security context by listening on core.request
  67.      *
  68.      * @param GetResponseEvent $event
  69.      */
  70.     public function onKernelRequest(GetResponseEvent $event)
  71.     {
  72.         if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
  73.             return;
  74.         }
  75.         if (null === $this->tokenStorage || null === $this->authorizationChecker) {
  76.             return;
  77.         }
  78.         $token $this->tokenStorage->getToken();
  79.         if (null !== $token && $token->isAuthenticated() && $this->authorizationChecker->isGranted(AuthenticatedVoter::IS_AUTHENTICATED_REMEMBERED)) {
  80.             $this->setUserValue($token->getUser());
  81.             $contextEvent = new SentryUserContextEvent($token);
  82.             $this->eventDispatcher->dispatch(SentrySymfonyEvents::SET_USER_CONTEXT$contextEvent);
  83.         }
  84.     }
  85.     /**
  86.      * @param GetResponseForExceptionEvent $event
  87.      */
  88.     public function onKernelException(GetResponseForExceptionEvent $event)
  89.     {
  90.         $exception $event->getException();
  91.         if ($this->shouldExceptionCaptureBeSkipped($exception)) {
  92.             return;
  93.         }
  94.         $this->eventDispatcher->dispatch(SentrySymfonyEvents::PRE_CAPTURE$event);
  95.         $this->client->captureException($exception);
  96.     }
  97.     /**
  98.      * This method only ensures that the client and error handlers are registered at the start of the command
  99.      * execution cycle, and not only on exceptions
  100.      *
  101.      * @param ConsoleCommandEvent $event
  102.      *
  103.      * @return void
  104.      */
  105.     public function onConsoleCommand(ConsoleCommandEvent $event)
  106.     {
  107.         // only triggers loading of client, does not need to do anything.
  108.     }
  109.     /**
  110.      * @param ConsoleExceptionEvent $event
  111.      */
  112.     public function onConsoleException(ConsoleExceptionEvent $event)
  113.     {
  114.         $command $event->getCommand();
  115.         $exception $event->getException();
  116.         if ($this->shouldExceptionCaptureBeSkipped($exception)) {
  117.             return;
  118.         }
  119.         $data = [
  120.             'tags' => [
  121.                 'command' => $command $command->getName() : 'N/A',
  122.                 'status_code' => $event->getExitCode(),
  123.             ],
  124.         ];
  125.         $this->eventDispatcher->dispatch(SentrySymfonyEvents::PRE_CAPTURE$event);
  126.         $this->client->captureException($exception$data);
  127.     }
  128.     protected function shouldExceptionCaptureBeSkipped(\Exception $exception)
  129.     {
  130.         foreach ($this->skipCapture as $className) {
  131.             if ($exception instanceof $className) {
  132.                 return true;
  133.             }
  134.         }
  135.         return false;
  136.     }
  137.     /**
  138.      * @param UserInterface | object | string $user
  139.      */
  140.     private function setUserValue($user)
  141.     {
  142.         $data = [];
  143.         $request $this->requestStack->getCurrentRequest();
  144.         if ($request instanceof Request) {
  145.             $data['ip_address'] = $request->getClientIp();
  146.         }
  147.         if ($user instanceof UserInterface) {
  148.             $this->client->set_user_data($user->getUsername(), null$data);
  149.             return;
  150.         }
  151.         if (is_string($user)) {
  152.             $this->client->set_user_data($usernull$data);
  153.             return;
  154.         }
  155.         if (is_object($user) && method_exists($user'__toString')) {
  156.             $this->client->set_user_data((string)$usernull$data);
  157.         }
  158.     }
  159. }