Yii:捕获特定控制器的所有异常

Eug*_*ene 17 yii

我正在开发一个包含REST API组件的项目.我有一个专用于处理所有REST API调用的控制器.

有没有办法捕获该特定控制器的所有异常,以便我可以对这些异常采取不同的操作而不是应用程序的其他控制器?

IE:我想回复包含异常消息的XML/JSON格式的API响应,而不是默认的系统视图/堆栈跟踪(在API上下文中并不真正有用).不希望不必在控制器中将每个方法调用包装在自己的try/catch中.

感谢提前的任何建议.

med*_*dve 37

您可以通过注册onErroronException事件侦听器来完全绕过Yii的默认错误显示机制.

例:

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

  // ...
}
Run Code Online (Sandbox Code Playgroud)


小智 9

我无法在控制器中附加事件,我通过重新定义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);
}
}
Run Code Online (Sandbox Code Playgroud)

在index.php中:

require_once(dirname(__FILE__) . '/protected/components/WebApplication.php');
Yii::createApplication('WebApplication', $config)->run();
Run Code Online (Sandbox Code Playgroud)