2012-07-06 115 views
16

我正在嘗試構建一個爲所有調用返回JSON的REST Web服務。通常,這是非常簡單的,我就是這樣做:如何捕獲Symfony2控制器操作中可能出現的所有異常?

return new Response(json_encode($return_object)); 

我的問題是,我應該怎麼截取一個全球性的方式異常?我想這樣做,因爲如果在我的應用程序的任何地方發生異常,我仍然希望向客戶端返回一條JSON消息,基本上說:「喲,我聽說你喜歡例外」。我的想法是,在成功和失敗的情況下返回JSON將簡化任何客戶端實現我的API所需的工作。

到目前爲止,我能想到的唯一的事情就是這樣寫的每個控制器動作:

public function generateMemeAction($arg1, $arg2) { 
    $return_object = array(); 
    try { 
    // stuff to generate meme here 
    $return_object['status'] = "GREAT SUCCESS!"; 
    } catch (Exception $e) { 
    // epic fail 
    $return_object['status'] = "UnluckyBrianException"; 
    } 
    return new Response(json_encode($return_object)); 
} 

這是所有偉大和美好,但try-catch塊將成爲每一個動作相同在我的應用程序中,每當我需要編輯一些複製麪食時,我都會覺得很蠢。專業提示?

回答

17

REST應用程序有不同類型的錯誤。例如。您可能會有邏輯錯誤或輸入錯誤(並非所有參數都已發送)。不同類型的錯誤應該使用不同的方式處理。對於這種情況,最好的辦法是手動處理這些錯誤。

你可以添加到你的控制器特殊的錯誤方法(並把它放入父類),這將返回錯誤代碼+錯誤文本。

但是,如果你想使用自動處理您可以使用異常監聽器:

這裏有一個例子:

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

public function onKernelException(GetResponseForExceptionEvent $event) 
{ 
    $exception = $event->getException(); 
    $response = new Response(); 
    // setup the Response object based on the caught exception 
    $event->setResponse($response); 

    // you can alternatively set a new Exception 
    // $exception = new \Exception('Some special exception'); 
    // $event->setException($exception); 
} 
+5

太棒了!謝謝Evgeny,這真的清除了一切。稍微深入一點,我發現如何訂閱該事件的功能:http://symfony.com/doc/current/cookbook/service_container/event_listener.html – robertdfrench 2012-07-07 02:14:26

+3

您也可以通過檢查請求來有條件地應用JSON格式頭文件並返回早期:'if(!$ event-> getRequest() - > headers-> contains('Accept','application/json'))return; – Tamlyn 2013-09-23 15:46:58

相關問題