2017-01-30 76 views
0

我在我的REST API項目中使用ZendFramework 3。所以有幾個模塊和一個插件來檢查授權狀態。如果授權失敗,則拋出異常。如何攔截ZendFramework 3中的異常

沒有辦法在每個控制器中分別使用try .. catch來處理它。我如何攔截並處理異常並生成像這樣的JSON輸出?

{ 
    message: "Access denied", 
    reason: "Your token is incorrect" 
} 

我是ZendFramework的新手,這就是爲什麼我不知道如何做到這一點。官方文件沒有對此說一句話。

回答

1

default framework Events被觸發,包括事件MvcEvent :: EVENT_DISPATCH_ERROR。所以,你應該做的就是在該錯誤事件上附加監聽器並返回JSON響應。

首先,你需要註冊監聽器在module.config.php

// In my case module name is Api 
'listeners'   => [ 
    Api\Listener\ApiListener::class // Register the class listener 
], 
'service_manager' => [ 
    'invokables' => [ 
     // Register the class (of course you can use Factory) 
     Api\Listener\ApiListener::class => Api\Listener\ApiListener::class 
    ], 
], 

其次,創建文件類的API /監聽器/ ApiListener.php

<?php 

namespace Api\Listener; 

use Zend\EventManager\AbstractListenerAggregate; 
use Zend\EventManager\EventManagerInterface; 
use Zend\Mvc\MvcEvent; 
use Zend\Console\Request as ConsoleRequest; 
use Zend\View\Model\JsonModel; 


class ApiListener extends AbstractListenerAggregate 
{ 

    public function attach(EventManagerInterface $events, $priority = 1) 
    { 
     // Registr the method which will be triggered on error 
     $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH_ERROR, 
     [$this, 'handleError'], 0); 
    } 


    /** 
    * Return JSON error on API URI(s) 
    */ 
    public function handleError(MvcEvent $e) 
    { 
     $request = $e->getParam('application')->getRequest(); 

     if($request instanceof ConsoleRequest){ 
      return; 
     } 

     //If you want to convert Response only on some URIs 
     //$uri = $request->getUri()->getPath(); 
     //if(0 !== strpos($uri, '/api')){ 
     // return; 
     //} 

     $response = $e->getResponse(); 
     $exception = $e->getResult()->exception; 
     $errorType = $e->getError(); 
     $errorCode = $exception && $exception->getCode() ? $exception->getCode() : 500; 
     $errorMsg = $exception ? $exception->getMessage() : $errorType; 
     $json  = new JsonModel(['message' => $errorMsg]); 

     $json->setTerminal(true); 
     $response->setStatusCode($errorCode); 
     $e->setResult($json); 
     $e->setViewModel($json); 
    } 

} 

這就是全部。現在每個錯誤都會執行您的自定義邏輯。