yii2 开发api接口时优雅的处理全局异常的方法
前言:个人觉得,学习或温习一套Web
框架,在快速阅读一遍文档后,应从路由,控制器,请求/响应对象,数据模型(Logic,Dao,Entity),全局异常处理
几个方面下手,这几项了解后,框架上手就游刃有余了。然后我比较喜欢在开工前整理好框架的全局异常处理,方便写 api
时错误的统一响应。
在api
接口的开发过程中,我们需要对用户数据进行严格的校验,防止非法输入对服务产生安全问题,在开发过程中,我比较喜欢即时的以抛出异常
的方式中断请求的处理,并以全局异常处理器
格式化处理后统一返回给客户端。
今天就把 yii2
自带的全局异常处理器改写至对 api
友好(yii2
的 yiiwebHttpException
默认对 web 请求友好,都是以text/html
的方式返回错误描述,对api
不友好,api
当然是json
)。
注册异常处理器
yii2
也是以 controller/action
的方式定义一个异常处理器的,我们可以在 components= errorHandler
中自定义。
# config/web.php
'components' = [
'errorHandler' = [
'errorAction' = 'exception/handler'
]
]
异常处理器
定义相应的异常处理器,appactionsErrorApiAction
继承 yiiwebErrorAction
,可以拿到yii2
为我们整理好的全局异常。
# controllers/ExceptionController.php
<?php
namespace appcontrollers;
use yiiwebController;
class ExceptionController extends Controller
{
/**
* 为 actionHandler 挂载独立的 action
* @return array
*/
public function actions()
{
return [
'handler' = [
'class' = 'appactionsErrorApiAction',
]
];
}
}
对api
友好的错误异常处理器,这里我也只是简单的把响应格式改了一下,异常的上下文还是用yii2
自带的处理的。
#actions/ErrorApiAction.php
<?php
/**
* @author wangzhijian@styd.com
* @date 2019-5-13 17:20:10
* Api 全局错误异常处理器
*/
namespace appactions;
use Yii;
use yiiwebErrorAction;
use yiiwebResponse;
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 appexceptions;
class HttpException extends yiiwebHttpException
{
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 appexceptions;
class HttpBadRequestException extends HttpException
{
public $statusCode = 400;
}
exceptions/HttpUnauthorizedException.php
<?php
/**
* 401 unauthorized
*/
namespace appexceptions;
class HttpUnauthorizedException extends HttpException
{
public $statusCode = 401;
}
exceptions/HttpForbiddenException.php
<?php
/**
* 403 forbidden
*/
namespace appexceptions;
class HttpForbiddenException extends HttpException
{
public $statusCode = 403;
}
exceptions/HttpNotFoundException.php
<?php
/**
* 404 not found
*/
namespace appexceptions;
class HttpNotFoundException extends HttpException
{
public $statusCode = 404;
}
使用范例
在一些 service logic model
中根据需要即时抛出异常即可,上层控制器拿到的永远都是正常的返回数据,绝对的2xx
响应簇
throw new HttpBadRequestException("具体的非法描述", 4001);
throw new HttpUnauthorizedException("请认证后访问");
throw new HttpForbiddenException("无权访问");
throw new HttpNotFoundException("请求资源不存在");
以上就是本文的全部内容,希望对大家的学习有所帮助。
- 微信年度重磅“小游戏”上线,罗胖一度退出的小程序正在逆袭
- 谈谈WCF中的Data Contract(2):WCF Data Contract对Generic的支持
- Android注解学习(1)
- [WCF权限控制]ASP.NET Roles授权[上篇]
- [WCF权限控制]ASP.NET Roles授权[下篇]
- 如何解决分布式系统中的跨时区问题[实例篇]
- Visual Studio对程序集签名时一个很不好用的地方
- 一个关于解决序列化问题的编程技巧
- [WCF权限控制]从两个重要的概念谈起:Identity与Principal[上篇]
- 从数据到代码——通过代码生成机制实现强类型编程[下篇]
- 谈谈你最熟悉的System.DateTime[下篇]
- 如何解决EnterLib异常处理框架最大的局限——基于异常"类型"的异常处理策略
- [WCF权限控制]从两个重要的概念谈起:Identity与Principal[下篇]
- 收藏!6道常见hadoop面试题及答案解析
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- React-Native Android打包
- React-Native iOS打包
- Webpack+Babel手把手带你搭建开发环境(内附配置文件)
- Redux 异步解决方案2. Redux-Saga中间件
- Redux异步解决方案 1. Redux-Thunk中间件
- 深度学习Pytorch检测实战 - Notes - 第1&2章 基础知识
- Java多线程编程在JMeter中应用
- Kubernetes 升级填坑指南(一)
- 根据 PID 获取 K8S Pod名称 - 反之 POD名称 获取 PID
- 用python实现一个verilog网表Parser
- 经典 | Python实例小挑战—Part eight
- python的数字与字符串相互转换
- 坑!url中含有中文导致nginx 400。锅是tomcat的
- pytest文档43-元数据使用(pytest-metadata)
- Python | 面试的常客,经典的生产消费者模式