2012-06-20 25 views
16

Estoy trabajando en un proyecto que incluye un componente REST API. Tengo un controlador dedicado a manejar todas las llamadas a la API REST.Yii: detecta todas las excepciones para un controlador específico

¿Hay alguna manera de detectar todas las excepciones para ese controlador específico para que pueda tomar una acción diferente para esas excepciones que el resto de los controladores de la aplicación?

IE: Me gustaría responder con una respuesta API con formato XML/JSON que contenga el mensaje de excepción, en lugar de la vista del sistema/seguimiento de la pila (que no es realmente útil en un contexto API). Preferiría no tener que envolver todas las llamadas de método en el controlador en su propio try/catch.

Gracias por cualquier consejo con antelación.

Respuesta

36

Puede completo error por defecto de derivación de Yii mostrando el mecanismo mediante el registro onError y onException detectores de eventos.

Ejemplo:

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

Gracias, lo he intentado todo tipo de cosas, pero la solución es, con mucho, la mejor manera de anular el error manejador/excepción para cosas como controlador de API. –

3

Puede escribir su propia función actionError() por controlador. Hay varias formas de hacer que el descrito here

9

I no fue capaz de adjuntar eventos en el controlador, y lo hice por clase redefinición 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); 
} 
} 

En index.php:

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

Estoy usando el siguiente controlador base para una API, no es una API sin estado, pero también puede servir.

BaseJSONController clase extiende 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); 
     } 
} 

También podría atrapar DBException y correo electrónico de las personas, ya que son un tanto crítico y puede mostrar un problema subyacente en el diseño de código/db.

0

añadir esto a su controlador:

Yii::app()->setComponents(array(
    'errorHandler'=>array(
     'errorAction'=>'error/error' 
    ) 
)); 
Cuestiones relacionadas