错误码规范¶
规范英文名:HiveNet Error Code Standards
规范中文名:HiveNet 错误码规范
HiveNet标识名:hivenet_error_code_standards
HiveNet版本:v1.1.0
错误码定义原则¶
唯一性原则¶
错误码的定义应保证唯一性,即同一个场景应能且只能对应到唯一的一个错误码,不应出现含义相同的两个不同错误码。
例如:已定义了“无此账号”,不应再定义“账号不存在”。
无歧义原则¶
错误码的定义应保证不会有歧义,即不应将多个场景的错误码定义到同一个错误码上。
例如:不应定义有以下这种错误码“余额不足/交易金额超限”。
细粒度原则¶
错误码的定义应尽可能向更细的粒度扩展,以确保能更加精确地反映实际场景。但由于场景变更、设计人员经验及成本原因,不太可能一开始就可以定义出最细粒度的错误码,因此还是会存在非最细粒度的错误码,但在使用中需尽量避免使用这类错误码。
例如:开始设计错误码时会有“累计金额超限”这种错误码,但随着后续发展可以细化为“转账日累计金额超过限额”、“转账月累计金额超过限额”这些更细化的错误码,这时候应将“累计金额超限”标识为汇总类错误码,后续应用尽量避免使用该错误码(但错误码仍保留以兼容旧系统)。
错误码定义¶
错误码定义为5位数字组成的字符串,其中第1位为错误类型编码(0-成功类,1-业务失败类,2-系统失败类,3-结果未知类),其余4位数字为错误明细编码,对应明确的错误信息。接口(函数)调用方收到错误码后,如果无需区分明细的错误,则可仅取错误类型编码(第1位)进行判断和处理;如果需区分明细错误,则应根据错误类型编码(第1位)及后4位错误明细编码明细进行错误的判断和处理。错误类型编码的说明和处理原则如下:
**0-成功类:**处理成功,其中00000为通用的成功代码;但也可以通过序号来定义不同的成功状态,例如对一个转账并通知客户的接口,可以定义以下的不同成功状态错误码:“00001-转账成功并短信通知、00002-转账成功并邮件通知”。
1-业务失败类:从业务角度看的正常失败情况,例如余额不足、账户已被冻结等情况;业务失败类的错误一般不认为是系统异常。
**2-系统失败类:**从系统角度看明确的异常处理失败情况,例如网络连接失败、数据插入失败等情况;系统失败类的错误说明系统存在问题,应进行监控并及时人工介入处理。
**3-结果未知类:**无法预知实际处理的情况应返回该类错误码,例如接口调用超时(或者调用下游系统的接口超时)、处理过程中的连接被重置等;调用方遇到结果未知类错误不能按成功或失败的逻辑进行处理,而是应该建立机制(例如自动轮询或人工查询)获取实际的处理结果后,再进行对用的处理。
错误明细编码统一管理¶
错误码明细编码(后4位)在HiveNet内部必须保证全局统一的,不允许各个系统各模块自行定义错误明细编码,而是必须使用发布的标准错误明细编码,如果所发布的错误明细编码不能涵盖各个系统及模块的应用需求,必须向HiveNet标准小组申请新增错误明细编码。
以下为几个固定的错误明细编码定义,已发布的错误明细编码见本标准的《附表-HiveNet错误明细编码清单》:
| 错误明细编码 | 汇总标志 | 错误描述 |
|---|---|---|
| 0000 | N | 成功 |
| 9999 | Y | 其他 |
API(网络接口)错误码要求¶
对于API(接口)的调用,对错误码扩展增加系统标识和模块标识的内容,以便于通过错误码直接定位错误发生的位置,通过API接口返回的错误码定义为13位,组成为“3位系统标识+4位模块标识+5位数字错误码”,例如‘MPCESSx00000’,具体说明如下:
系统标识:必填,大写字母,以信息科技部公布的系统清单中的标识为准,例如MPC(中台系统),不足3位的情况右补小写字母“x”
模块标识:选填,大写字母,不填的情况为4个小写字母“x”;填入的是系统内部的模块标识,以中台系统为例,模块标识‘ESSx’(加密服务系统),不足4位的情况右补小写字母“x”
错误码:必填,5位数字,统一管理的统一错误码;其中第1位为错误类型编码(0-成功类,1-业务失败类,2-系统失败类,3-结果未知类)
系统标识及模块标识应用指引¶
通过错误码的系统标识和模块标识,可以直接定位到出问题的系统及模块,因此在错误码生成时应按照以下的规则进行处理:
(1)系统自身产生的错误,系统标识和模块标识应按本系统的实际标识填写;
(2)系统在调用其他接口(函数)时产生的错误,系统标识及模块标识应填写被调用方的实际标识;
(3)系统在调用其他接口(函数),被调用方有返回错误码的情况,如果系统本身无特殊需求进行屏蔽的话,应直接透传被调用方的错误码;
(4)系统在调用其他接口(函数),被调用方有返回错误码的情况,如果系统本身需进行特殊处理时(例如调用下游出现系统错误,但本系统处于中间状态需返回未知),应根据实际情况改变错误类型编码,以及错误码明细编码。
举例说明如下:
(1)接口调用关系为 A > B > C,每个环节都成功,对于B来说应直接透传C返回的错误码,即A收到的错误码为C00000;
(2)接口调用关系为 A > B > C,C处理失败,对于B来说应直接透传C返回的错误码,即A收到的错误码为C20001;
(3)接口调用关系为 A > B > C,B调C的接口时出现网络错误,对于B来说是C的服务存在问题,所以错误码的标识应该置C,即A收到的错误码为C20002;
(4)接口调用关系为 A > B > C,B自身处理失败(例如校验不通过),对于B来说是自身服务出现问题,所以错误码的标识应该自身,即A收到的错误码为B20002;
(5)接口调用关系为 A > B > C、D、E,每个环节都成功,由于B是调用C、D、E的汇集点,而不是透传点,因此返回的错误码系统标识使用B的标识,即A收到的错误码为B00000;
(6)接口调用关系为 A > B > C、D、E,C调用失败,则认为错误发生点是C,因此返回的错误码系统标识使用C的标识,即A收到的错误码为C20001;
(7)接口调用关系为 A > B > C、D、E,C、D、E必须顺序调用,当D调用失败,则认为错误发生点是D,且B处于中间状态需把状态置为未知,则返回的错误码系统标识使用D的标识,以及需改变错误类型编码和错误码明细编码,即A收到的错误码为D30001;
系统内部方法(函数)错误码要求¶
应用错误码的场景¶
系统内部函数返回值有以下3种场景
具体值:不涉及判断错误的场景,直接返回所需的返回值,这类场景无需应用错误码规范的编码
bool类型:只需判断执行成功、失败,这类场景无需应用错误码规范的编码
执行状态:函数执行有多种状态,需要通过编码区分的,必须使用标准的错误码规范
错误码应用要求¶
函数执行有多种状态的场景,返回值必须为HiveNetCore.generic.CResult对象,通过该对象返回错误码信息及自定义返回值,该对象的固定属性包括:
CResult.code : 5位数字错误码
CResult.msg : 错误信息,如果使用国际化(i18n)控件,则为国际化信息的消息ID
CResult.error :发生异常时的sys.exc_info()三元组对象(type, value, traceback)中的type,从获取到的异常中得到类型名称,它是BaseException 的子类
CResult.trace_str :发生异常时的错误追踪堆栈日志(traceback.format_exc())便于输出日志记录
此外,CResult对象可以支持直接增加自定义属性,用于回传函数所需的返回实际内容,例如:
cresult_obj.net_info = [socket, id]
模块错误定位(扩展)¶
如果系统内的函数调用也需要类似API调用一样,分析错误发生的位置,可对CResult对象增加一个固定的moudle属性标识出错的模块(建议传入的值为模块名),模块传递的规则与”API(网络接口)错误码要求”一致。
附表-HiveNet错误明细编码清单¶
成功错误编码(0000 - 0099)¶
| 错误明细编码 | 英文描述 | 中文描述 | 备注 |
|---|---|---|---|
| 0000 | success | 成功 |
用户行为错误编码(0100 - 0399)¶
| 错误明细编码 | 英文描述 | 中文描述 | 备注 |
|---|---|---|---|
| 0100 | user cancel | 用户中断操作 | |
| 0101 | user close app | 用户关闭应用 |
网络通讯错误编码(0400-0599)¶
| 代码值 | 英文描述 | 中文描述 | 备注 |
|---|---|---|---|
| 0401 | connect to [$1:$2] failure, error info: [$3] | 连接地址[$1:$2]建立失败, 错误信息: [$3] | $1: IP地址;$2: 端口;$3: 失败信息 |
| 0402 | connection timed out | 连接超时 | |
| 0403 | receive timed out | 获取数据超时 | |
| 0404 | send timed out | 发送数据超时 | |
| 0405 | receive failure | 获取数据失败 | |
| 0406 | send failure | 发送数据失败 | |
| 0407 | get client connection timed out | 获取客户端连接超时 | |
| 0408 | grpc call failure, status code: [$1], details: [$2] | grpc调用失败,状态码: [$1],详细信息: [$2] | |
| 0409 | ip address verify failure | IP地址验证失败 | |
| 0599 | other network failure | 网络连接其他失败 |
数据库错误编码(0600-0799)¶
| 代码值 | 英文描述 | 中文描述 | 备注 |
|---|---|---|---|
| 0799 | other database failure | 数据库处理其他失败 |
操作系统错误编码(0800-0999)¶
| 代码值 | 英文描述 | 中文描述 | 备注 |
|---|---|---|---|
| 0801 | dir or file [$1] not exists | 路径或文件 [$1] 不存在 | |
| 0802 | [$1] is not a dir | [$1] 不是一个路径 | |
| 0803 | [$1] is not a file | [$1] 不是一个文件 | |
| 0999 | other system failure | 其他系统失败 |
函数调用错误编码(1000-1399)¶
| 代码值 | 英文描述 | 中文描述 | 备注 | | —— | —————————————————- | ———————————— | —- | | 1001 | unsupport argument | 不支持的参数 | | | 1002 | can’t find operate object | 找不到操作对象 | | | 1003 | argument consistency error | 参数一致性检查错误 | | | 1004 | parallel task force stop | 并发任务强制中止 | | | 1005 | execute over time | 执行超时 | | | 1006 | argument [$1] isn’t nullable | 参数[$1]不可为空 | | | 1007 | execute raise exception, type “[$1]” | 执行抛出异常,异常类型“[$1]” | | | 1008 | remote function execute raise exception, type “[$1]” | 远程函数执行抛出异常,异常类型“[$1]” | | | 1399 | function call other failure | 函数调用其他失败 | |
应用服务错误编码(1400-1599)¶
| 代码值 | 英文描述 | 中文描述 | 备注 |
|---|---|---|---|
| 1401 | service start failure - service have been started | 服务启动失败-服务已启动 | |
| 1402 | service stop failure - service have been shutdown | 服务停止失败-服务已关闭 | |
| 1403 | service name "[$1]" is not existed | 服务名"[$1]"不存在 | |
| 1404 | unsupport command "[$1]" | 不支持的命令"[$1]" | |
| 1405 | service name "[$1]" is existed | 服务名"[$1]"已存在 | |
| 1599 | other application failure | 应用服务处理其他失败 |
业务错误编码(3000-4999)¶
| 代码值 | 英文描述 | 中文描述 | 备注 |
|---|---|---|---|
| 3001 | [$1] is existed | [$1]已存在 | |
| 3002 | [$1] is not existed | [$1]不存在 | |
| 3003 | validators failed | 校验失败 | |
| 3004 | get info failed | 获取信息失败 | |
| 3005 | control check failed | 控制检查失败 | |
| 3006 | user confirmation required | 需要用户确认 | |
| 3007 | signature error | 签名检查失败 | |
| 3008 | timestamp expired | 时间戳已过期 | |
| 3009 | username format error | 用户名格式错误 | |
| 3010 | username is existed | 用户名已存在 | |
| 3011 | username is not existed | 用户名不存在 | |
| 3012 | user is locked | 用户被锁定 | |
| 3013 | user status is abnormal | 用户状态异常 | |
| 3014 | login status has expired | 登录状态已过期 | |
| 3015 | without permission to perform the current operation | 没有权限执行当前操作 | |
| 4999 | other business failure | 其他业务失败 |