请选择 进入手机版 | 继续访问电脑版
绿茶科技社区

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
这篇文章主要介绍了yii2 开发api接口时优雅的处理全局异常的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
前言:个人觉得,学习或温习一套Web框架,在快速阅读一遍文档后,应从路由,控制器,请求/响应对象,数据模型(Logic,Dao,Entity),全局异常处理几个方面下手,这几项了解后,框架上手就游刃有余了。然后我比较喜欢在开工前整理好框架的全局异常处理,方便写 api时错误的统一响应。
在api接口的开发过程中,我们需要对用户数据进行严格的校验,防止非法输入对服务产生安全问题,在开发过程中,我比较喜欢即时的以抛出异常的方式中断请求的处理,并以全局异常处理器格式化处理后统一返回给客户端。
今天就把 yii2 自带的全局异常处理器改写至对 api 友好(yii2的 yii\web\HttpException默认对 web 请求友好,都是以text/html的方式返回错误描述,对api不友好,api当然是json)。
注册异常处理器
yii2也是以 controller/action 的方式定义一个异常处理器的,我们可以在 components=>errorHandler中自定义。
  1. # config/web.php
  2. 'components' => [
  3.   'errorHandler' => [
  4.     'errorAction' => 'exception/handler'
  5.   ]
  6. ]
复制代码
异常处理器

定义相应的异常处理器,app\actions\ErrorApiAction 继承 yii\web\ErrorAction,可以拿到yii2为我们整理好的全局异常。
  1. # controllers/ExceptionController.php
  2. <?php
  3.   
  4. namespace app\controllers;
  5.   
  6. use yii\web\Controller;
  7.   
  8. class ExceptionController extends Controller
  9. {
  10.   /**
  11.    * 为 actionHandler 挂载独立的 action
  12.    * @return array
  13.    */
  14.   public function actions()
  15.   {
  16.     return [
  17.       'handler' => [
  18.         'class' => 'app\actions\ErrorApiAction',
  19.       ]
  20.     ];
  21.   }
  22. }
复制代码
对api友好的错误异常处理器,这里我也只是简单的把响应格式改了一下,异常的上下文还是用yii2自带的处理的。
  1. #actions/ErrorApiAction.php
  2. <?php
  3. /**
  4. * @author wangzhijian@styd.com
  5. * @date 2019-5-13 17:20:10
  6. * Api 全局错误异常处理器
  7. */
  8.   
  9. namespace app\actions;
  10.   
  11. use Yii;
  12. use yii\web\ErrorAction;
  13. use yii\web\Response;
  14.   
  15. class ErrorApiAction extends ErrorAction
  16. {
  17.   public function run()
  18.   {
  19.     // 根据异常类型设定相应的响应码
  20.     Yii::$app->getResponse()->setStatusCodeByException($this->exception);
  21.     // json 格式返回
  22.     Yii::$app->getResponse()->format = Response::FORMAT_JSON;
  23.     // 返回的内容数据
  24.     return [
  25.       'msg' => $this->exception->getMessage(),
  26.       'err' => $this->exception->getCode()
  27.     ];
  28.   }
  29. }
复制代码
异常实体

主要是简单的把状态码的传递封装一下,用更容易理解的类名来代理传递。
exceptions/HttpException.php
  1. <?php
  2. /**
  3. * app 异常基础类
  4. */
  5.   
  6. namespace app\exceptions;
  7.   
  8. class HttpException extends \yii\web\HttpException
  9. {
  10.   public function __construct($message = null, $code = 0, \Exception $previous = null)
  11.   {
  12.     parent::__construct($this->statusCode, $message, $code, $previous);
  13.   }
  14. }
复制代码

exceptions/HttpForbiddenException.php
  1. <?php
  2. /**
  3. * 400 bad request
  4. */
  5.   
  6. namespace app\exceptions;
  7.   
  8. class HttpBadRequestException extends HttpException
  9. {
  10.   public $statusCode = 400;
  11. }
复制代码

exceptions/HttpUnauthorizedException.php
  1. <?php
  2. /**
  3. * 401 unauthorized
  4. */
  5.   
  6. namespace app\exceptions;
  7.   
  8. class HttpUnauthorizedException extends HttpException
  9. {
  10.   public $statusCode = 401;
  11. }
复制代码

exceptions/HttpForbiddenException.php
  1. <?php
  2. /**
  3. * 403 forbidden
  4. */
  5.   
  6. namespace app\exceptions;
  7.   
  8. class HttpForbiddenException extends HttpException
  9. {
  10.   public $statusCode = 403;
  11. }
复制代码

exceptions/HttpNotFoundException.php
  1. <?php
  2. /**
  3. * 404 not found
  4. */
  5.   
  6. namespace app\exceptions;
  7.   
  8. class HttpNotFoundException extends HttpException
  9. {
  10.   public $statusCode = 404;
  11. }
复制代码
使用范例

在一些 service logic model 中根据需要即时抛出异常即可,上层控制器拿到的永远都是正常的返回数据,绝对的2xx响应簇
  1. throw new HttpBadRequestException("具体的非法描述", 4001);
  2. throw new HttpUnauthorizedException("请认证后访问");
  3. throw new HttpForbiddenException("无权访问");
  4. throw new HttpNotFoundException("请求资源不存在");
复制代码




分享到 :
0 人收藏

3 个回复

倒序浏览
周见智  高级会员 | 2019-8-12 09:39:42
我只是路过的......
haolujun  高级会员 | 2019-8-23 21:12:54
纯粹路过,没任何兴趣,仅仅是看在老用户份上回复一下
 高级会员 | 2019-9-9 20:44:37
一直在看
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

举报|Archiver|手机版|小黑屋|Lvchakeji Inc.  

Powered by Discuz! X3.3 © 2001-2016 Comsenz Inc.

返回顶部