2017-06-05 103 views
0

对于Stripe可能根据某些情况抛出的所有异常,我有一个Stripe异常包装。我试图为抛出的异常注册一个事件监听器,但似乎并没有解雇这个监听器。Symfony3注册异常监听器

不是在json响应中返回事件,而是抛出500并渲染堆栈跟踪。有什么我失踪了吗?

// AppBundle/Exceptions/StripePaymentException.php 
namespace AppBundle\Exceptions; 

use Exception; 

class StripePaymentException extends Exception { 

    public $response; 
    public $message; 

    public function __construct($message, $response, $code = 0, Exception $previous = null) 
    { 
     parent::__construct($message, $code); 

     $this->message = $message; 
     $this->response = $response; 
    } 

    public function getResponse() 
    { 
     return $this->$response; 
    } 

} 

// AppBundle/EventListener/StripePaymentExceptionListener.php 
namespace AppBundle\EventListener; 

use Symfony\Component\HttpFoundation\JsonResponse; 
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; 

class StripePaymentExceptionListener 
{ 
    public function onKernelException(GetResponseForExceptionEvent $event) 
    { 
     $exception = $event->getException(); 
     $data = $exception->getResponse(); 
     $response = new JsonResponse($data); 
     $event->setResponse($response); 
    } 
} 

// services.yml 
app.stripe_payment_exception_listener: 
class: AppBundle\EventListener\StripePaymentExceptionListener 
    tags: 
     - { name: kernel.event_listener, event: kernel.exception, priority: 200 } 
+0

究竟哪个错误你检索? –

+0

@AlessandroMinoccheri因此,异常被抛出,但它没有按照我期待的方式(通过侦听器)进行格式化。它抛出一个500,并呈现一个新的页面,而不是仅仅返回一个响应。 – mashedpotatoes

回答

0

它可能是您的自定义侦听器上的priority设置。如果在之前有另一个侦听器正在被触发,那么这绝不会实际返回异常。

你可以改变priority这里:

// services.yml 
app.stripe_payment_exception_listener: 
class: AppBundle\EventListener\StripePaymentExceptionListener 
    tags: 
     - { name: kernel.event_listener, event: kernel.exception, priority: 1 } 

或者你也可以改变你的“标准”的ExceptionListener到餐桌基于异常的抓类型:

if(instanceof $exception STRIPE_EXCEPTION_CLASS) 
    $data = $exception->getResponse(); 
    $response = new JsonResponse($data); 
    $event->setResponse($response); 
} 
else { 
    //"normal" behavior here 
} 

...或基于对Accept类型的标头

//if you're accepting json, return json 
if($accept->has('application/json')) { 
    $response = new Response(json_encode($data, JSON_FORCE_OBJECT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); 
    $response->headers->set('Content-Type', 'application/json; charset=utf-8'); 
    $event->setResponse($response); 
} 
//if accepting xml, return xml.. 
elseif($request->isXmlHttpRequest()) { 
    $xml = new \SimpleXMLElement('<exception/>'); 
    $data = array_flip($data); 
    array_walk_recursive($data, array ($xml, 'addChild')); 
    $response = new Response($xml->asXML()); 
    $response->headers->set('Content-Type', 'text/xml; charset=utf-8'); 
    $event->setResponse($response); 
} 
+0

我试着改变优先级。当我运行'php bin/console debug:event-dispatcher kernel.exception'时,StripePaymentExceptionListener是第一个按顺序排列的。但是,当引发异常时,它似乎没有触及监听器(尝试放置xdebug断点和var_dump,但都不起作用)。 – mashedpotatoes

+0

您是否尝试过在调用setResponse之后添加'return'语句? –