2017-04-14 9 views
1

例外処理のリスナーを作成します。以下は、私のコードは、私がプロダクションモードで致命的な例外のために行う必要がありますどのような追加作業Symfony2カーネルの例外イベントが運用モードで致命的なエラー例外を処理しない

services.yml

kernel.listener.prod_exception_listener: 
    class: MyBundle\Listener\ExceptionListener 
    tags: 
     - { name: kernel.event_listener, event: kernel.exception, method: onKernelException } 

ExceptionListener.php

<?php 
namespace MyBundle\Listener; 

use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; 
use Symfony\Component\HttpFoundation\Response; 
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; 

class ExceptionListener 
{ 
    public function onKernelException(GetResponseForExceptionEvent $event) 
    { 
     // no fatal exception goes here others are coming in this function 
     // like 403,404,500 are coming in this block 

    } 
} 

のですか? devモードでは致命的なエラーがリスナーに流入するためです。

答えて

0

私は私の応答の工場がどのように見える、それは私のservices.ymlで

api_exception_subscriber: 
    class: AppBundle\EventListener\ApiExceptionSubscriber 
    arguments: ['%kernel.debug%', '@api.response_factory', '@logger'] 
    tags: 
     - { name: kernel.event_subscriber } 
api.response_factory: 
    class: AppBundle\Api\ResponseFactory 

を次のように解決:

<?php 

namespace AppBundle\Api; 

use Symfony\Component\HttpFoundation\JsonResponse; 

class ResponseFactory 
{ 
    public function createResponse(ApiProblem $apiProblem) 
    { 
     $data = $apiProblem->toArray(); 

     $response = new JsonResponse(
      $data, 
      $apiProblem->getStatusCode() 
     ); 
     $response->headers->set('Content-Type', 'application/json'); 

     return $response; 
    } 
} 

とAPI subscriperクラス

<?php 

namespace AppBundle\EventListener; 

use AppBundle\Api\ApiProblem; 
use AppBundle\Api\ApiProblemException; 
use AppBundle\Api\ResponseFactory; 
use Psr\Log\LoggerInterface; 
use Symfony\Component\EventDispatcher\EventSubscriberInterface; 
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; 
use Symfony\Component\HttpKernel\KernelEvents; 
use Symfony\Component\HttpFoundation\JsonResponse; 
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; 

class ApiExceptionSubscriber implements EventSubscriberInterface 
{ 
    private $debug; 

    private $responseFactory; 

    private $logger; 

    public function __construct($debug, ResponseFactory $responseFactory, LoggerInterface $logger) 
    { 
     $this->debug = $debug; 
     $this->responseFactory = $responseFactory; 
     $this->logger = $logger; 
    } 

    public function onKernelException(GetResponseForExceptionEvent $event) 
    { 
     // only reply to /api URLs 
     if (strpos($event->getRequest()->getPathInfo(), '/api') !== 0) { 
      return; 
     } 

     $e = $event->getException(); 

     $statusCode = $e instanceof HttpExceptionInterface ? $e->getStatusCode() : 500; 

     // allow 500 errors to be thrown 
     if ($this->debug && $statusCode >= 500) { 
      return; 
     } 

     $this->logException($e); 

     if ($e instanceof ApiProblemException) { 
      $apiProblem = $e->getApiProblem(); 
     } else { 


      $apiProblem = new ApiProblem(
       $statusCode 
      ); 

      /* 
      * If it's an HttpException message (e.g. for 404, 403), 
      * we'll say as a rule that the exception message is safe 
      * for the client. Otherwise, it could be some sensitive 
      * low-level exception, which should *not* be exposed 
      */ 
      if ($e instanceof HttpExceptionInterface) { 
       $apiProblem->set('detail', $e->getMessage()); 
      } 
     } 

     $response = $this->responseFactory->createResponse($apiProblem); 

     $event->setResponse($response); 
    } 

    public static function getSubscribedEvents() 
    { 
     return array(
      KernelEvents::EXCEPTION => 'onKernelException' 
     ); 
    } 

    /** 
    * Adapted from the core Symfony exception handling in ExceptionListener 
    * 
    * @param \Exception $exception 
    */ 
    private function logException(\Exception $exception) 
    { 
     $message = sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', get_class($exception), $exception->getMessage(), $exception->getFile(), $exception->getLine()); 
     $isCritical = !$exception instanceof HttpExceptionInterface || $exception->getStatusCode() >= 500; 
     $context = array('exception' => $exception); 
     if ($isCritical) { 
      $this->logger->critical($message, $context); 
     } else { 
      $this->logger->error($message, $context); 
     } 
    } 
} 
関連する問題