src/AppBundle/Listener/ExceptionListener.php line 27

Open in your IDE?
  1. <?php
  2. namespace AppBundle\Listener;
  3. use AppBundle\Common\ExceptionPrintingToolkit;
  4. use Codeages\Biz\Framework\Service\Exception\AccessDeniedException;
  5. use Codeages\Biz\Framework\Service\Exception\NotFoundException;
  6. use Symfony\Component\DependencyInjection\ContainerInterface;
  7. use Symfony\Component\HttpFoundation\JsonResponse;
  8. use Symfony\Component\HttpFoundation\Request;
  9. use Symfony\Component\HttpFoundation\Response;
  10. use Symfony\Component\HttpKernel\Event\ExceptionEvent;
  11. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  12. use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
  13. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  14. use Topxia\Service\Common\ServiceKernel;
  15. class ExceptionListener
  16. {
  17.     private $container;
  18.     public function __construct(ContainerInterface $container)
  19.     {
  20.         $this->container $container;
  21.     }
  22.     public function onKernelException(ExceptionEvent $event)
  23.     {
  24.         $exception $event->getThrowable();
  25.         $request $event->getRequest();
  26.         $exception $this->convertException($exception);
  27.         if (!$request->isXmlHttpRequest()) {
  28.             $this->setTargetPath($request);
  29.             $event->setThrowable($exception);
  30.             return;
  31.         }
  32.         $statusCode $this->getStatusCode($exception);
  33.         $error $this->getErrorDetails($exception$statusCode);
  34.         $response = new JsonResponse(['error' => $error], $statusCode);
  35.         $event->setResponse($response);
  36.     }
  37.     protected function setTargetPath(Request $request)
  38.     {
  39.         if ($request->hasSession() && $request->isMethodSafe(false) && !$request->isXmlHttpRequest()) {
  40.             $request->getSession()->set('_target_path'$request->getUri());
  41.         }
  42.     }
  43.     private function getErrorDetails($exception$statusCode)
  44.     {
  45.         $error = ['name' => 'Error'];
  46.         if ($this->container->get('kernel')->isDebug()) {
  47.             $error['message'] = $exception->getMessage();
  48.             $error['trace'] = ExceptionPrintingToolkit::printTraceAsArray($exception);
  49.         } elseif ($exception instanceof HttpExceptionInterface) {
  50.             $error['message'] = $exception->getMessage();
  51.         } else {
  52.             $error['message'] = 'Request occurs an error';
  53.         }
  54.         if (403 === $statusCode) {
  55.             $user $this->getUser();
  56.             if ($user) {
  57.                 return ['name' => 'AccessDenied''message' => $this->getServiceKernel()->trans('访问被拒绝!')];
  58.             }
  59.             return ['name' => 'Unlogin''message' => $this->getServiceKernel()->trans('当前操作,需要登录!')];
  60.         }
  61.         return $error;
  62.     }
  63.     public function getUser()
  64.     {
  65.         if (!$this->container->has('security.token_storage')) {
  66.             throw new \LogicException('The SecurityBundle is not registered in your application.');
  67.         }
  68.         if (null === $token $this->container->get('security.token_storage')->getToken()) {
  69.             return null;
  70.         }
  71.         if (!is_object($user $token->getUser())) {
  72.             return null;
  73.         }
  74.         return $user;
  75.     }
  76.     private function convertException($exception)
  77.     {
  78.         if ($exception instanceof AccessDeniedException) {
  79.             return new AccessDeniedHttpException($exception->getMessage(), $exception);
  80.         }
  81.         if ($exception instanceof NotFoundException) {
  82.             return new NotFoundHttpException($exception->getMessage(), $exception);
  83.         }
  84.         return $exception;
  85.     }
  86.     private function getStatusCode($exception)
  87.     {
  88.         if (method_exists($exception'getStatusCode')) {
  89.             return $exception->getStatusCode();
  90.         }
  91.         $statusCode $exception->getCode();
  92.         if (array_key_exists($statusCodeResponse::$statusTexts)) {
  93.             return $statusCode;
  94.         }
  95.         return Response::HTTP_INTERNAL_SERVER_ERROR;
  96.     }
  97.     protected function getServiceKernel()
  98.     {
  99.         return ServiceKernel::instance();
  100.     }
  101. }