欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

yii2 开发api接口时优雅的处理全局异常的方法

程序员文章站 2023-02-17 15:50:11
前言:个人觉得,学习或温习一套web框架,在快速阅读一遍文档后,应从路由,控制器,请求/响应对象,数据模型(logic,dao,entity),全局异常处理几个方面下手,这...

前言:个人觉得,学习或温习一套web框架,在快速阅读一遍文档后,应从路由,控制器,请求/响应对象,数据模型(logic,dao,entity),全局异常处理几个方面下手,这几项了解后,框架上手就游刃有余了。然后我比较喜欢在开工前整理好框架的全局异常处理,方便写 api时错误的统一响应。

api接口的开发过程中,我们需要对用户数据进行严格的校验,防止非法输入对服务产生安全问题,在开发过程中,我比较喜欢即时的以抛出异常的方式中断请求的处理,并以全局异常处理器格式化处理后统一返回给客户端。

今天就把 yii2 自带的全局异常处理器改写至对 api 友好(yii2yii\web\httpexception默认对 web 请求友好,都是以text/html的方式返回错误描述,对api不友好,api当然是json)。

注册异常处理器

yii2也是以 controller/action 的方式定义一个异常处理器的,我们可以在 components=>errorhandler中自定义。

# config/web.php
'components' => [
  'errorhandler' => [
    'erroraction' => 'exception/handler'
  ]
]

异常处理器

定义相应的异常处理器,app\actions\errorapiaction 继承 yii\web\erroraction,可以拿到yii2为我们整理好的全局异常。

# controllers/exceptioncontroller.php
<?php

namespace app\controllers;

use yii\web\controller;

class exceptioncontroller extends controller
{
  /**
   * 为 actionhandler 挂载独立的 action
   * @return array
   */
  public function actions()
  {
    return [
      'handler' => [
        'class' => 'app\actions\errorapiaction',
      ]
    ];
  }
}

api友好的错误异常处理器,这里我也只是简单的把响应格式改了一下,异常的上下文还是用yii2自带的处理的。

#actions/errorapiaction.php
<?php
/**
 * @author wangzhijian@styd.com
 * @date 2019-5-13 17:20:10
 * api 全局错误异常处理器
 */

namespace app\actions;

use yii;
use yii\web\erroraction;
use yii\web\response;

class errorapiaction extends erroraction
{
  public function run()
  {
    // 根据异常类型设定相应的响应码
    yii::$app->getresponse()->setstatuscodebyexception($this->exception);
    // json 格式返回
    yii::$app->getresponse()->format = response::format_json;
    // 返回的内容数据
    return [
      'msg' => $this->exception->getmessage(),
      'err' => $this->exception->getcode()
    ];
  }
}

异常实体

主要是简单的把状态码的传递封装一下,用更容易理解的类名来代理传递。
exceptions/httpexception.php

<?php
/**
 * app 异常基础类
 */

namespace app\exceptions;

class httpexception extends \yii\web\httpexception
{
  public function __construct($message = null, $code = 0, \exception $previous = null)
  {
    parent::__construct($this->statuscode, $message, $code, $previous);
  }
}

exceptions/httpforbiddenexception.php

<?php
/**
 * 400 bad request
 */

namespace app\exceptions;

class httpbadrequestexception extends httpexception
{
  public $statuscode = 400;
}

exceptions/httpunauthorizedexception.php

<?php
/**
 * 401 unauthorized
 */

namespace app\exceptions;

class httpunauthorizedexception extends httpexception
{
  public $statuscode = 401;
}

exceptions/httpforbiddenexception.php

<?php
/**
 * 403 forbidden
 */

namespace app\exceptions;

class httpforbiddenexception extends httpexception
{
  public $statuscode = 403;
}

exceptions/httpnotfoundexception.php

<?php
/**
 * 404 not found
 */

namespace app\exceptions;

class httpnotfoundexception extends httpexception
{
  public $statuscode = 404;
}

使用范例

在一些 service logic model 中根据需要即时抛出异常即可,上层控制器拿到的永远都是正常的返回数据,绝对的2xx响应簇

throw new httpbadrequestexception("具体的非法描述", 4001);
throw new httpunauthorizedexception("请认证后访问");
throw new httpforbiddenexception("无权访问");
throw new httpnotfoundexception("请求资源不存在");

yii2 开发api接口时优雅的处理全局异常的方法

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。