2012-06-20 29 views
16

Tôi đang làm việc trên một dự án bao gồm một thành phần REST API. Tôi có một bộ điều khiển chuyên dụng để xử lý tất cả các cuộc gọi REST API.Yii: Bắt tất cả ngoại lệ cho một bộ điều khiển cụ thể

Có cách nào để nắm bắt tất cả ngoại lệ cho bộ điều khiển cụ thể đó để tôi có thể thực hiện một hành động khác cho những ngoại lệ đó so với phần còn lại của bộ điều khiển của ứng dụng không?

IE: Tôi muốn trả lời bằng phản hồi API được định dạng XML/JSON có chứa thông báo ngoại lệ, thay vì theo dõi hệ thống/ngăn xếp mặc định (không thực sự hữu ích trong ngữ cảnh API). Không muốn phải bọc tất cả các cuộc gọi phương thức trong bộ điều khiển trong thử/nắm bắt riêng của nó.

Cảm ơn mọi lời khuyên trước.

Trả lời

36

Bạn có thể hoàn toàn lỗi mặc định bypass Yii của hiển thị cơ chế bằng cách đăng ký onerroronException nghe sự kiện.

Ví dụ:

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

Cảm ơn, tôi đã thử tất cả các loại điều, nhưng giải pháp của bạn là do sự xa cách tốt nhất để ghi đè lỗi xử lý/ngoại lệ cho những thứ như điều khiển API. –

3

Bạn có thể viết hàm actionError() của riêng bạn trên mỗi bộ điều khiển. Có một số cách để làm điều đó được mô tả here

9

Tôi đã không thể đính kèm các sự kiện trong bộ điều khiển, và tôi đã làm nó bằng lớp định nghĩa lại CWebApplication:

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); 
} 
} 

Trong index.php:

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

Tôi đang sử dụng bộ điều khiển Cơ sở sau cho API, nó không phải là API không trạng thái, hãy nhớ bạn, nhưng nó có thể phục vụ tốt.

lớp BaseJSONController kéo dài 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); 
     } 
} 

Bạn cũng có thể bắt dbException và gửi email cho những người, như họ đang hơi quan trọng và có thể hiển thị vấn đề tiềm ẩn trong thiết kế mã/db.

0

Thêm này để điều khiển của bạn:

Yii::app()->setComponents(array(
    'errorHandler'=>array(
     'errorAction'=>'error/error' 
    ) 
)); 
Các vấn đề liên quan