[ Index ]

PHP Cross Reference of phpBB-3.3.2-deutsch

title

Body

[close]

/vendor/symfony/http-kernel/EventListener/ -> ExceptionListener.php (source)

   1  <?php
   2  
   3  /*
   4   * This file is part of the Symfony package.
   5   *
   6   * (c) Fabien Potencier <fabien@symfony.com>
   7   *
   8   * For the full copyright and license information, please view the LICENSE
   9   * file that was distributed with this source code.
  10   */
  11  
  12  namespace Symfony\Component\HttpKernel\EventListener;
  13  
  14  use Psr\Log\LoggerInterface;
  15  use Symfony\Component\Debug\Exception\FlattenException;
  16  use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  17  use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  18  use Symfony\Component\HttpFoundation\Request;
  19  use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
  20  use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
  21  use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
  22  use Symfony\Component\HttpKernel\HttpKernelInterface;
  23  use Symfony\Component\HttpKernel\KernelEvents;
  24  use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
  25  
  26  /**
  27   * ExceptionListener.
  28   *
  29   * @author Fabien Potencier <fabien@symfony.com>
  30   */
  31  class ExceptionListener implements EventSubscriberInterface
  32  {
  33      protected $controller;
  34      protected $logger;
  35      protected $debug;
  36  
  37      public function __construct($controller, LoggerInterface $logger = null, $debug = false)
  38      {
  39          $this->controller = $controller;
  40          $this->logger = $logger;
  41          $this->debug = $debug;
  42      }
  43  
  44      public function onKernelException(GetResponseForExceptionEvent $event)
  45      {
  46          $exception = $event->getException();
  47          $request = $event->getRequest();
  48          $eventDispatcher = \func_num_args() > 2 ? func_get_arg(2) : null;
  49  
  50          $this->logException($exception, sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', \get_class($exception), $exception->getMessage(), $exception->getFile(), $exception->getLine()));
  51  
  52          $request = $this->duplicateRequest($exception, $request);
  53  
  54          try {
  55              $response = $event->getKernel()->handle($request, HttpKernelInterface::SUB_REQUEST, false);
  56          } catch (\Exception $e) {
  57              $this->logException($e, sprintf('Exception thrown when handling an exception (%s: %s at %s line %s)', \get_class($e), $e->getMessage(), $e->getFile(), $e->getLine()));
  58  
  59              $prev = $e;
  60              do {
  61                  if ($exception === $wrapper = $prev) {
  62                      throw $e;
  63                  }
  64              } while ($prev = $wrapper->getPrevious());
  65  
  66              $prev = new \ReflectionProperty($wrapper instanceof \Exception ? \Exception::class : \Error::class, 'previous');
  67              $prev->setAccessible(true);
  68              $prev->setValue($wrapper, $exception);
  69  
  70              throw $e;
  71          }
  72  
  73          $event->setResponse($response);
  74  
  75          if ($this->debug && $eventDispatcher instanceof EventDispatcherInterface) {
  76              $cspRemovalListener = function (FilterResponseEvent $event) use (&$cspRemovalListener, $eventDispatcher) {
  77                  $event->getResponse()->headers->remove('Content-Security-Policy');
  78                  $eventDispatcher->removeListener(KernelEvents::RESPONSE, $cspRemovalListener);
  79              };
  80              $eventDispatcher->addListener(KernelEvents::RESPONSE, $cspRemovalListener, -128);
  81          }
  82      }
  83  
  84      public static function getSubscribedEvents()
  85      {
  86          return [
  87              KernelEvents::EXCEPTION => ['onKernelException', -128],
  88          ];
  89      }
  90  
  91      /**
  92       * Logs an exception.
  93       *
  94       * @param \Exception $exception The \Exception instance
  95       * @param string     $message   The error message to log
  96       */
  97      protected function logException(\Exception $exception, $message)
  98      {
  99          if (null !== $this->logger) {
 100              if (!$exception instanceof HttpExceptionInterface || $exception->getStatusCode() >= 500) {
 101                  $this->logger->critical($message, ['exception' => $exception]);
 102              } else {
 103                  $this->logger->error($message, ['exception' => $exception]);
 104              }
 105          }
 106      }
 107  
 108      /**
 109       * Clones the request for the exception.
 110       *
 111       * @param \Exception $exception The thrown exception
 112       * @param Request    $request   The original request
 113       *
 114       * @return Request The cloned request
 115       */
 116      protected function duplicateRequest(\Exception $exception, Request $request)
 117      {
 118          $attributes = [
 119              '_controller' => $this->controller,
 120              'exception' => FlattenException::create($exception),
 121              'logger' => $this->logger instanceof DebugLoggerInterface ? $this->logger : null,
 122          ];
 123          $request = $request->duplicate(null, null, $attributes);
 124          $request->setMethod('GET');
 125  
 126          return $request;
 127      }
 128  }


Generated: Wed Nov 11 20:28:18 2020 Cross-referenced by PHPXref 0.7.1