NingG +

基础原理系列:异常信息和异常码

1. 简介

当请求异常时,需要两类异常信息:

  1. 用户可见的异常信息(外部异常信息):用于告知用户发生了什么情况,方便用户进行下一步操作
  2. 开发人员可见的异常信息(内部异常信息):用户开发人员快速定位问题

几个典型问题:

  1. 抛出内部异常:要求给出详细的信息,快速定位问题发生的场景,方便重现错误;
  2. 异常信息的转换:内部异常要转换为外部异常,屏蔽过多的异常细节,为用户提供简要的说明信息,引导用户的下一步操作

2. 内部异常信息

疑问:

  1. 内部异常的种类有哪些?
  2. 如何进行分类管理?分类是为了统一和规范

异常分类,可以通过不同维度进行:

  1. 业务实体维度:
    1. 实体A 相关
    2. 实体B 相关
    3. 实体通用
  2. 业务上,异常产生原因维度:
    1. 资源不存在
    2. 状态不合法
    3. 输入参数不合法
    4. 没有操作权限
  3. 异常发生位置:
    1. 用户输入不合法:用户引发的错误
    2. Controller 层的错误
    3. Service 层的错误
    4. DAO 层的错误

实际上,因为编写代码是业务逻辑代码,因此,倾向于从异常产生原因+业务实体的维度划分异常,举例:

  1. 异常1:资源不存在,资源类型为”项目”,id:100
  2. 异常2:资源状态不合法,资源类型为”项目”,id:100,资源状态为 A,无法取消

3. 外部异常信息

疑问:

  1. 外部异常的种类有哪些?
  2. 如何进行分类管理?分类是为了统一和规范

外部异常信息,实际上是基于内部异常信息做了一层处理:

  1. 封装
  2. 转换
  3. 归类

无论内部异常有多少,最终给外部的异常种类,还是越少越好,而且要简洁,外部异常的目标聚焦在为用户提供简要的说明信息,引导用户的下一步操作。

4. 实践

4.1. 错误码

4.1.1. 现有方案调研

几种错误码对比:

4.1.2. 经验总结

4.1.3. 实例

下面给一组实际使用的错误码:

错误码 对应异常 作用 备注
30001 ParamErrorException 参数错误  
40001 NeedLoginException 你需要登录  
40003 ForbiddenException 您没有资源的操作权限, 资源:%s, 资源唯一标识和取值, %s:%s  
40009 ResourceAlreadyExistException 资源已存在, 资源类型:%s, 资源唯一标识和取值, %s:%s  
40010 ResourceNotFoundException 资源不存在, 资源类型:%s, 资源唯一标识和取值, %s:%s  
40011 ResourceAlreadyDeletedException 资源已删除, 资源类型:%s, 资源唯一标识和取值, %s:%s  
40012 ResourceDuplicateKeyException 唯一性约束条件限制, %s操作失败, 资源类型:%s, 资源唯一标识和取值, %s:%s  
50000 InnerServerErrorException 服务器内部错误  
50001 ThriftException 服务器内部远程调用异常, 详细信息: %s  

4.2. 异常命名

常用的异常命名:

异常命名 说明
TypeNotMatch 类型不匹配
IllegalStatus 非法的状态
IllegalParam 参数不正确
InvalidParam 参数无效
ResourceNotFound 资源不存在
ResourceAlreadyDeleted 资源已经删除
ResourceAlreadyExist 资源已存在
ResourceNoPermission 没有资源权限
SystemError 系统内部错误

不必约束在上面的命名中,异常可以随时随地命名,有助于快速定位错误,例如下面这样:

上面异常命名很流畅,有几个可以借鉴的地方:

5. 其他

5.1. HTTP 状态码

简要列出几类 HTTP 状态码:

状态码 说明
1xx 信息提示
2xx 成功
3xx 重定向(要求浏览器进行下一步动作)
4xx 客户端错误
5xx 服务器错误

6. 参考来源

  1. 微信公众平台,全局返回码
  2. 支付宝,开放平台,公共错误码
  3. 微博 API,错误代码
  4. 有效处理 Java 异常三原则
  5. 异常处理的误区和经验总结
  6. HTTP 状态码
Top