百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 博客教程 > 正文

关于错误码的那点事

connygpt 2024-08-20 13:50 7 浏览

一、什么是错误码

错误码一般情况分为对外错误码,系统内部错误码。

对外错误码常应用在一些开放接口,比如http接口,rpc接口等,通过错误码的形式给予上游更加友好的错误提示以及错误描述。

系统内部错误码,存在于关系紧密的微服务之间、或者程序的上下游中。因为某种业务错误、或者系统不可用造成的错误,开发人员可以根据错误码、错误信息进行具体定位;或者根据上游根据错误码做业务逻辑判断,从而保证整体流程完整性。

总而言之,错误码的作用: 指出错误的原因,快速定位问题,指导上游系统做出正确的业务判断,引导用户进行正确的操作。因此构建一个通用且架构清晰的错误码体系是一件很有必要的事情。

那么怎么定义一种对外对内都友好的错误码呢?至今业内也并没有一个比较好的方案或者规范。这里结合新老支付系统融合,逐步进行摸索。

二、支付系统错误码现状

由于历史原因,公司内部目前有两套运行中的钱包系统。为了提高钱包系统可用性以及性能,对两套钱包系统进行迁移整合升级优化。但迁移合并两套钱包系统的途中,发现两套钱包系统、以及之前现存的已经优化过的错误码之前存在冲突、类型不一致、定义混乱、随意性高等问题。

由于其一钱包系统之前由其他团队开发维护,后期也对其进行重构过,这造成了新钱包系统的错误码定义规则存在两套;从代码角度来看,新老钱包系统在设计之初的时候,对错误码的定义都各自定义了一个比较合适的规范,但是在后期开发维护中,越来越少的开发人员去遵循规范定义错误码,最终造成了由错误描述决定错误码的现象。而目前新系统中错误码,在设计之初,并未考虑到未来整合带来的错误码冲突等问题,造成了部分错误码重合,语义大相径庭的问题,所以重新定义错误码规范也是迫在眉睫。

钱包系统错误码现状:

钱包一错误码定义: 6位错误码。 首位表示错误类型,区分系统级别、校验、rpc服务调用错误。 这种设计方式,第一位是明确的,后面5位都是预留的错误码,长度足够,满足后续错误码的增加;缺点错误码对应的类型太少,会出现相同语义的错误码,对应不同的首位数字。后重构版本的错误码修改了原有的错误码位数,修改后7位。造成了该系统的接口层,6位错误码,7位错误码混乱,并且错误码没有分类,全部顺序后排。

钱包二错误码定义: 提供错误码工具类,规定了大多数钱包常用的错误码;然后以此为基础,进行增加。优点: 错误码分类清晰,结构明了,缺点: 不容易根据错误码定位具体错误

简单来说,目前钱包系统错误码存在以下问题

1. 错误码字段类型定义不一致。有的定义数值类型,有的定义字符串类型

2.错误码重合问题。相同的错误码,在不同系统中有着不同的语义

三、调研业内接口定义

鉴于当前支付系统错误码的痛点,如错误码应该用数值类型还是字符串类型,长度命名格式是怎样的等问题,调研了多家大厂的API规范以及接口定义,来探索适用于支付系统的错误码规范。

  1. 微信支付

a. 参考微信支付v2接口

微信支付v2接口: 协议:http, content-type: text/xml

参考链接: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

原格式是xml,为了更加直观,这里先加工为json格式
{
    "return_code":"SUCCESS",  //  SUCCESS/FAIL 此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断
    "return_msg":"OK",
    "result_code":"SUCCESS", // SUCCESS/FAIL  标识业务成功失败
    "err_code":"SYSTEMERROR", // 当result_code为FAIL的时候,该值返回业务错误码
    "err_code_des":"系统错误"
}

微信支付错误码结构为三级结构:

一级、公共错误码(网关层) 。该层仅返回通信成功失败信息

二级、业务错误码 (总): 表示该业务是否处理成功

三级、具体业务错误码

业务错误码举例:

error_code

err_code_des

NOAUTH

商户无此接口权限

INVALID_REQUEST

参数错误

NOTENOUGH

余额不足

b.参考微信支付v3接口

微信支付v3接口: 协议:http, content-type: application/json

参考链接: https://pay.weixin.qq.com/wiki/doc/apiv3/Share/error_code.shtml

err_code

http_code

err_msg

USERPAYING

202

用户正在付款中

OUT_TRADE_NO_USED

403

商户订单号重复

ORDERNOTEXIST

404

订单不存在

根据微信v3的接口文档可知,微信支付返回的业务错误的同时,会返回一个与之对应的httpcode。当http_code的状态码在[200,300)之间,认为该请求是有合法的返回的;当大于300时,判断接口返回一定是有异常错误的。微信支付V3 sdk封装了http_code与err_code的相关处理。

对外暴露http接口,在抛出业务错误的同时,也要抛出相同语义的httpcode,这就需要开发人员明确httpcode语义。 这样的劣势在于学习成本较高,依赖开发人员对httpcode的熟练程度,可能会出现 httpcode语义与业务错误语义不一致的现象。

2.支付宝错误码定义

参考链接: https://opendocs.alipay.com/open/common/105806

不同业务的业务错误码: 举一个接口的例子 https://opendocs.alipay.com/apis#%E4%B8%9A%E5%8A%A1%E9%94%99%E8%AF%AF%E7%A0%81

sub_code、sub_msg这两个参数标识支付宝返回的业务错误码、业务错误信息;

{
    "code":"",//网关返回码
    "msg":"",//网关返回码
    "sub_code":"ACQ.INVALID_PARAMETER",
    "sub_msg":"参数无效"
}

支付宝的错误码定义 与 微信支付的v2接口定义风格比较相像。

支付宝错误码结构分为两级: 一级: 网关, 二级: 业务错误码。

请求支付宝接口,先通过支付宝网关系统,网关系统进行验签、加解密、流控等功能,如果网关校验出错,则抛出公共错误码。网关校验成功之后,交给下游业务系统,sub_code都是语义明确的错误码,以及错误描述。

3. google Api规范

参考链接: https://www.bookstack.cn/read/API-design-guide/API-design-guide-07-%E9%94%99%E8%AF%AF.md

google的错误码定义中,将返回码的结构定义为

message Status {
  // A simple error code that can be easily handled by the client. The
  // actual error code is defined by `google.rpc.Code`.
  int32 code = 1;
  // A developer-facing human-readable error message in English. It should
  // both explain the error and offer an actionable resolution to it.
  string message = 2;
  // Additional error information that the client code can use to handle
  // the error, such as retry delay or a help link.
  repeated google.protobuf.Any details = 3;
}

其中 code: 是错误码,message: 是具体的错误信息,detail是根据这个错误,推荐调用方采取怎样的措施。

google对于错误码的定义,是比较简洁的。一个大类分配一个code;并不会因为多个相似的错误类型提供多个code。

google规范里details信息: 表示该错误的具体原因,定义参考: https://github.com/googleapis/googleapis/blob/master/google/rpc/error_details.proto

detail里面定义了 retryable信息 可以表示该错误码返回是可以进行重试的,并且给出推荐的重试延迟时间、QuotaFailure信息表示配额出错、限流超限等;badRequest可以详细的给出为什么会报这种错误 等等开发人员可以根据这样详细的错误返回码作出正确的反应。

4. 微博 规范

参考api: https://open.weibo.com/wiki/Error_code

{
    "request" : "/statuses/home_timeline.json",
    "error_code" : "20502",
    "error" : "Need you follow uid."
}

20502 其中 错误码的组成: 1位 错误级别编号(系统、服务) + 2位服务模块(比如 网关、微博、评价、私信 比较像服务标识) + 2位 错误代码(自定义的错误编码)

2

05

02

服务级错误(1为系统级错误)

服务模块代码

具体错误代码

微博的错误码有明确的结构语义。将服务系统标识,显示在错误码中。这个操作与支付宝错误码构成有一点相像。第一位 标识服务级、系统级的字段,不确定是否是表示该错误是有网关抛出、还是说明确几种系统级别的错误,按分类抛出。

5.阿里巴巴的JAVA技术手册

阿里巴巴规范

第一点: 说明了错误码的特点: 要简单明了;

第二点: 错误码最好定义为string字符串类型: 来源 + 错误编号 (这样,错误码的数值可以携带更多的信息)

第三点: 避免随意添加错误码、避免直接暴露错误码给到用户侧

综上所述, 通过调研的这几家的对外文档来看,错误码的定义业内并没有一个统一的规范。但是大体的设计思路如下:

a. 错误码类型为字符串类型

b. 系统如果由网关→ 内部服务构成,则错误码分为两级

c. 错误码可以标识出抛出错误的来源服务。

d. 错误码可以抽象出来两种 公共错误码、业务错误码

四、思考与结论

结合上述调研的行业错误码定义,以及当前钱包系统现状。由于支付系统处于整体业务流程的最基础层,提供支付、付款等RPC能力,不存在直接对外暴露http接口的可能。所以微信支付、支付宝支付的三层错误码结构并不适用于钱包系统。

借鉴上述调研的api,错误码定义成字符串类型,更适用于业务场景,方便于后期的业务扩展。而google规范中对于错误码场景定义的统一规范,在一定程度上又降低了开发人员随意定义新错误码的可能。所以在error_code的场景定义上参考google-api规范

错误码error_code: 字符串. 前N位为当前业务所属领域标识,优势: 易于区分其他业务错误码,如果后期由于业务扩展、或者业务缩小带来的服务拆分合并,错误码仍然可以保持当前的设置。

提取公共常用的错误:

参考google规范进行归集: https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto

RPC接口常用错误

error_code

内部错误

115

该请求不支持

112

状态错误

110

请求频繁

109

没有权限类错误

108

权限校验错误

107

已存在类错误

106

不存在类错误

105

超时类错误

104

参数错误

103

未知错误
(比如调用下游接口出错,可以抛这个异常)

101

其他业务错误码,可以使用200~999错误段进行自定义设置;但是如果有错误语义命中上述错误,则需要优先选择上述错误码。

五、RPC错误码结构定义

exception RpcError{
    1:required string err_code;
    2:required string err_desc;
}
  1. 错误码定义:

构成: 业务+错误码类型+自定义业务编码; 其中自定义业务编码是系统自定义的。

标识处理业务

错误码类型(3)

自定义业务编码(2)

参数校验失败:
{
    "err_code":"WORDER.10501",
    "err_desc":"交易不存在"
}
WORDER:表示当前错误发生时,所处理的业务标识
105: 不存在
01: 交易不存在
02: 用户不存在
03: 订单不存在
...

2. err_desc: 错误信息

错误信息 开发人员可以快速定位问题。

3. 错误要抛出来

接口如果处理出错了,包装好合适的错误码以及错误描述,将该错误throw出,而不是将错误包在接口返回参数中。由于公司使用的是thrift协议-http,并且监控告警强依赖于httpCode,将错误直接抛出去,可以使监控更加有效的监控RPC接口,避免处理出错,但是返回httpcode是200的场景。

六、网关类型的httpcode设计

  1. httpcode基础

错误码

代表含义

2xx

成功

3xx

重定向

4xx

客户端原因引起的错误

5xx

服务器原因引起的错误

2. http服务返回

{
    "code":"0", // 成功:0  失败:返回对应错误码
    "message":"",
    "data":{ //接口实际处理结果
 
    },
    "pagination":{
        "is_end":false,
        "is_first":true,
        "offset":20,
        "limit":20,
        "total":1000
    }
}

3 错误信息转换

http接口,如果接口返回成功。则httpcode错误码返回200;如果失败,可以按需返回上述httpcode。

http接口一般分为两种,第一种: 内部http接口; 第二种,与前端进行交互。内部http接口,错误码可以参照rpc接口;外部接口,避免将内部错误码外露出去,对用户展示的错误描述,最好可以在http层进行转换,不要将内部错误描述直接暴露出去。

七、展望

在系统迁移、重构、优化的时候,经常会遇到由于原有系统设计不合理,后续赶时间堆需求,造成的系统日益难以维护的问题。本次主要针对迁移过程中,遇到的错误码定义混乱这一问题,提出调研、以及自己的思考。目标能够统一错误码格式的规范,以及rpc、http类型接口的错误定义规范。在后续系统迁移过程中,使用规范的错误定义,降低上游系统理解错误的复杂度,并且在一定程度上可以降低运维效率。

在后续的规划中,针对规范的错误码使用,可以有更多的技术设想,比如错误集成SDK,内部包含错误码定义,以及错误的打点上报,错误监控大盘等。


作者:任我去留

出处:https://zhuanlan.zhihu.com/p/411726319

相关推荐

自学Python,写一个挨打的游戏代码来初识While循环

自学Python的第11天。旋转~跳跃~,我~闭着眼!学完循环,沐浴着while的光芒,闲来无事和同事一起扯皮,我说:“编程语言好神奇,一个小小的循环,竟然在生活中也可以找到原理和例子”,同事也...

常用的 Python 工具与资源,你知道几个?

最近几年你会发现,越来越多的人开始学习Python,工欲善其事必先利其器,今天纬软小编就跟大家分享一些常用的Python工具与资源,记得收藏哦!不然下次就找不到我了。1、PycharmPychar...

一张思维导图概括Python的基本语法, 一周的学习成果都在里面了

一周总结不知不觉已经自学Python一周的时间了,这一周,从认识Python到安装Python,再到基本语法和基本数据类型,对于小白的我来说无比艰辛的,充满坎坷。最主要的是每天学习时间有限。只...

三日速成python?打工人,小心钱包,别当韭菜

随着人工智能的热度越来越高,许多非计算机专业的同学们也都纷纷投入到学习编程的道路上来。而Python,作为一种相对比较容易上手的语言,也越来越受欢迎。网络上各类网课层出不穷,各式广告令人眼花缭乱。某些...

Python自动化软件测试怎么学?路线和方法都在这里了

Python自动化测试是指使用Python编程语言和相关工具,对软件系统进行自动化测试的过程。学习Python自动化测试需要掌握以下技术:Python编程语言:学习Python自动化测试需要先掌握Py...

Python从放弃到入门:公众号历史文章爬取为例谈快速学习技能

这篇文章不谈江流所专研的营销与运营,而聊一聊技能学习之路,聊一聊Python这门最简单的编程语言该如何学习,我完成的第一个Python项目,将任意公众号的所有历史文章导出成PDF电子书。或许我这个Py...

【黑客必会】python学习计划

阅读Python文档从Python官方网站上下载并阅读Python最新版本的文档(中文版),这是学习Python的最好方式。对于每个新概念和想法,请尝试运行一些代码片段,并检查生成的输出。这将帮助您更...

公布了!2025CDA考试安排

CDA数据分析师报考流程数据分析师是指在不同行业中专门从事行业数据搜集、整理、分析依据数据作出行业研究评估的专业人员CDA证书分为1-3级,中英文双证就业面广,含金量高!!?报考条件:满18...

一文搞懂全排列、组合、子集问题(经典回溯递归)

原创公众号:【bigsai】头条号:程序员bigsai前言Hello,大家好,我是bigsai,longtimenosee!在刷题和面试过程中,我们经常遇到一些排列组合类的问题,而全排列、组合...

「西法带你学算法」一次搞定前缀和

我花了几天时间,从力扣中精选了五道相同思想的题目,来帮助大家解套,如果觉得文章对你有用,记得点赞分享,让我看到你的认可,有动力继续做下去。467.环绕字符串中唯一的子字符串[1](中等)795.区...

平均数的5种方法,你用过几种方法?

平均数,看似很简单的东西,其实里面包含着很多学问。今天,分享5种经常会用到的平均数方法。1.算术平均法用到最多的莫过于算术平均法,考试平均分、平均工资等等,都是用到这个。=AVERAGE(B2:B11...

【干货收藏】如何最简单、通俗地理解决策树分类算法?

决策树(Decisiontree)是基于已知各种情况(特征取值)的基础上,通过构建树型决策结构来进行分析的一种方式,是常用的有监督的分类算法。决策树算法是机器学习中的一种经典算法,它通过一系列的规则...

面试必备:回溯算法详解

我们刷leetcode的时候,经常会遇到回溯算法类型题目。回溯算法是五大基本算法之一,一般大厂也喜欢问。今天跟大家一起来学习回溯算法的套路,文章如果有不正确的地方,欢迎大家指出哈,感谢感谢~什么是回溯...

「机器学习」决策树——ID3、C4.5、CART(非常详细)

决策树是一个非常常见并且优秀的机器学习算法,它易于理解、可解释性强,其可作为分类算法,也可用于回归模型。本文将分三篇介绍决策树,第一篇介绍基本树(包括ID3、C4.5、CART),第二篇介绍Ran...

大话AI算法: 决策树

所谓的决策树算法,通俗的说就是建立一个树形的结构,通过这个结构去一层一层的筛选判断问题是否好坏的算法。比如判断一个西瓜是否好瓜,有20条西瓜的样本提供给你,让你根据这20条(通过机器学习)建立起...