2012-06-20 6 views
16

私はREST APIコンポーネントを含むプロジェクトを作成しています。私は、すべてのREST APIコールを処理するためのコントローラを用意しています。Yii:特定のコントローラのすべての例外をキャッチ

特定のコントローラのすべての例外をキャッチして、アプリケーションのコントローラの残りの部分とは異なる例外を処理する方法はありますか?

IE:デフォルトのシステムビュー/スタックトレース(APIコンテキストではあまり役に立ちません)ではなく、例外メッセージを含むXML/JSON形式のAPIレスポンスを返信したいと思います。独自のtry/catchでコントローラ内のすべてのメソッド呼び出しをラップする必要はありません。

事前にアドバイスをいただき、ありがとうございます。

答えて

36

を説明しています。

例:

class ApiController extends CController 
{ 
    public function init() 
    { 
    parent::init(); 

    Yii::app()->attachEventHandler('onError',array($this,'handleError')); 
    Yii::app()->attachEventHandler('onException',array($this,'handleError')); 
    } 

    public function handleError(CEvent $event) 
    {   
    if ($event instanceof CExceptionEvent) 
    { 
     // handle exception 
     // ... 
    } 
    elseif($event instanceof CErrorEvent) 
    { 
     // handle error 
     // ... 
    } 

    $event->handled = TRUE; 
    } 

    // ... 
} 
+0

おかげで、私は物事のすべての並べ替えをしようとしましたが、あなたのソリューションは、これまででAPIコントローラのようなもののためにエラー/例外ハンドラを上書きするための最良の方法です。 –

3

コントローラーごとに独自のactionError()関数を記述できます。それを行うにはいくつかの方法が、あなたは完全にのonErroronExceptionをイベントリスナーを登録することにより、表示機構のYiiのデフォルトのエラーを回避することができますhere

9

私は、コントローラ内のイベントを添付することができませんでした、と私は、再定義CWebApplicationクラスでそれをやった:index.phpの中

class WebApplication extends CWebApplication 
{ 
protected function init() 
{ 
    parent::init(); 

    Yii::app()->attachEventHandler('onError',array($this, 'handleApiError')); 
    Yii::app()->attachEventHandler('onException',array($this, 'handleApiError')); 
} 

/** 
* Error handler 
* @param CEvent $event 
*/ 
public function handleApiError(CEvent $event) 
{ 
    $statusCode = 500; 

    if($event instanceof CExceptionEvent) 
    { 
     $statusCode = $event->exception->statusCode; 
     $body = array(
      'code' => $event->exception->getCode(), 
      'message' => $event->exception->getMessage(), 
      'file' => YII_DEBUG ? $event->exception->getFile() : '*', 
      'line' => YII_DEBUG ? $event->exception->getLine() : '*' 
     ); 
    } 
    else 
    { 
     $body = array(
      'code' => $event->code, 
      'message' => $event->message, 
      'file' => YII_DEBUG ? $event->file : '*', 
      'line' => YII_DEBUG ? $event->line : '*' 
     ); 
    } 

    $event->handled = true; 

    ApiHelper::instance()->sendResponse($statusCode, $body); 
} 
} 

require_once(dirname(__FILE__) . '/protected/components/WebApplication.php'); 
Yii::createApplication('WebApplication', $config)->run(); 
0

次のBase ControllerをAPIに使用していますが、ステートレスAPIではありませんが、まあまあ役立ちます。

クラスBaseJSONControllerはCControllerを拡張{

 public $data = array(); 

     public $layout; 

     public function filters() 
     { 
       return array('mainLoop'); 
     } 

     /** 
     * it all starts here 
     * @param unknown_type $filterChain 
     */ 
     public function filterMainLoop($filterChain){ 
       $this->data['Success'] = true; 
       $this->data['ReturnMessage'] = ""; 
       $this->data['ReturnCode'] = 0; 
       try{ 
         $filterChain->run(); 

       }catch (Exception $e){ 
         $this->data['Success'] = false; 
         $this->data['ReturnMessage'] = $e->getMessage(); 
         $this->data['ReturnCode'] = $e->getCode(); 
       } 

       echo json_encode($this->data); 
     } 
} 

はまたdbExceptionを捕まえることができ、彼らはやや重要だとコード/ DB設計に根本的な問題を示すことができるよう、それらを電子メールで送信します。

0

あなたのコントローラにこれを追加します。

Yii::app()->setComponents(array(
    'errorHandler'=>array(
     'errorAction'=>'error/error' 
    ) 
)); 
関連する問題