vendor/friendsofsymfony/rest-bundle/Controller/ExceptionController.php line 65

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the FOSRestBundle package.
  4.  *
  5.  * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace FOS\RestBundle\Controller;
  11. use FOS\RestBundle\Util\ExceptionValueMap;
  12. use FOS\RestBundle\View\View;
  13. use FOS\RestBundle\View\ViewHandlerInterface;
  14. use Symfony\Component\HttpFoundation\Request;
  15. use Symfony\Component\HttpFoundation\Response;
  16. use Symfony\Component\Debug\Exception\FlattenException as LegacyFlattenException;
  17. use Symfony\Component\ErrorRenderer\Exception\FlattenException;
  18. use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
  19. use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
  20. /**
  21.  * Custom ExceptionController that uses the view layer and supports HTTP response status code mapping.
  22.  */
  23. class ExceptionController
  24. {
  25.     /**
  26.      * @var ViewHandlerInterface
  27.      */
  28.     private $viewHandler;
  29.     /**
  30.      * @var ExceptionValueMap
  31.      */
  32.     private $exceptionCodes;
  33.     /**
  34.      * @var bool
  35.      */
  36.     private $showException;
  37.     public function __construct(
  38.         ViewHandlerInterface $viewHandler,
  39.         ExceptionValueMap $exceptionCodes,
  40.         $showException
  41.     ) {
  42.         $this->viewHandler $viewHandler;
  43.         $this->exceptionCodes $exceptionCodes;
  44.         $this->showException $showException;
  45.     }
  46.     /**
  47.      * Converts an Exception to a Response.
  48.      *
  49.      * @param Request                   $request
  50.      * @param \Exception|\Throwable     $exception
  51.      * @param DebugLoggerInterface|null $logger
  52.      *
  53.      * @throws \InvalidArgumentException
  54.      *
  55.      * @return Response
  56.      */
  57.     public function showAction(Request $request$exceptionDebugLoggerInterface $logger null)
  58.     {
  59.         $currentContent $this->getAndCleanOutputBuffering($request->headers->get('X-Php-Ob-Level', -1));
  60.         $code $this->getStatusCode($exception);
  61.         $templateData $this->getTemplateData($currentContent$code$exception$logger);
  62.         $view $this->createView($exception$code$templateData$request$this->showException);
  63.         $response $this->viewHandler->handle($view);
  64.         return $response;
  65.     }
  66.     /**
  67.      * @param \Exception $exception
  68.      * @param int        $code
  69.      * @param array      $templateData
  70.      * @param Request    $request
  71.      * @param bool       $showException
  72.      *
  73.      * @return View
  74.      */
  75.     protected function createView(\Exception $exception$code, array $templateDataRequest $request$showException)
  76.     {
  77.         $view = new View($exception$code$exception instanceof HttpExceptionInterface $exception->getHeaders() : []);
  78.         $view->setTemplateVar('raw_exception');
  79.         $view->setTemplateData($templateData);
  80.         return $view;
  81.     }
  82.     /**
  83.      * Determines the status code to use for the response.
  84.      *
  85.      * @param \Exception $exception
  86.      *
  87.      * @return int
  88.      */
  89.     protected function getStatusCode(\Exception $exception)
  90.     {
  91.         // If matched
  92.         if ($statusCode $this->exceptionCodes->resolveException($exception)) {
  93.             return $statusCode;
  94.         }
  95.         // Otherwise, default
  96.         if ($exception instanceof HttpExceptionInterface) {
  97.             return $exception->getStatusCode();
  98.         }
  99.         return 500;
  100.     }
  101.     /**
  102.      * Determines the template parameters to pass to the view layer.
  103.      *
  104.      * @param string               $currentContent
  105.      * @param int                  $code
  106.      * @param \Exception           $exception
  107.      * @param DebugLoggerInterface $logger
  108.      *
  109.      * @return array
  110.      */
  111.     private function getTemplateData($currentContent$code, \Exception $exceptionDebugLoggerInterface $logger null)
  112.     {
  113.         if (class_exists(FlattenException::class)) {
  114.             $exception FlattenException::createFromThrowable($exception);
  115.         } else {
  116.             $exception LegacyFlattenException::create($exception);
  117.         }
  118.         return [
  119.             'exception' => $exception,
  120.             'status' => 'error',
  121.             'status_code' => $code,
  122.             'status_text' => array_key_exists($codeResponse::$statusTexts) ? Response::$statusTexts[$code] : 'error',
  123.             'currentContent' => $currentContent,
  124.             'logger' => $logger,
  125.         ];
  126.     }
  127.     /**
  128.      * Gets and cleans any content that was already outputted.
  129.      *
  130.      * This code comes from Symfony and should be synchronized on a regular basis
  131.      * see src/Symfony/Bundle/TwigBundle/Controller/ExceptionController.php
  132.      *
  133.      * @return string
  134.      */
  135.     private function getAndCleanOutputBuffering($startObLevel)
  136.     {
  137.         if (ob_get_level() <= $startObLevel) {
  138.             return '';
  139.         }
  140.         Response::closeOutputBuffers($startObLevel 1true);
  141.         return ob_get_clean();
  142.     }
  143. }