Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >令人头疼的错误码(上)

令人头疼的错误码(上)

作者头像
一个无聊的人
发布于 2022-08-26 01:52:58
发布于 2022-08-26 01:52:58
2.5K00
代码可运行
举报
运行总次数:0
代码可运行

前言

业界错误码的规范很多,但是阅读发现这些规范各不相同,甚至很多点相悖。前段时间查了很多资料、咨询过阿里百度等几家公司的同学整理出一份材料和同事分享交流过一轮,下面是一些汇总,这里是希望各路大神们不吝赐教,一起整理出一份最佳实践。

什么是错误码

我并没有找到错误码的明确定义,各公司对错误码的定义相同,个人比较倾向于亚马逊官方文档给出的定义:通过对错误码定义,能够简单的帮助用户或开发者识别和理解异常性质,错误码与错误不是一对一关系,是错误类型的一种抽象代号。这里划重点:错误码表示一类错误。

错误码作用

错误码的作用很多,平时会用来:

1)通过日志进行问题排查,快速定位问题。 2)后端服务之间错误码传递。 3)前端展示的错误提示(错误提示是根据错误码决定)。 4)通过错误码配置监控大盘(强烈推荐,每个接口上报错误码到监控系统,发布服务时查看错误曲线,异常情况一目了然)。

错误码作用很多,但是我认为错误码最基本、最重要是作用是回答:出了什么问题?哪里出了问题?如何处理?

遇到的问题

下面我总结了遇到的四个问题,以及谷歌、华为等几家公司是如何解决的:

问题一:错误描述与错误控制杂糅。

错误码既要负责描述发生了什么错误,又要负责决定出错后如何进行出错控制,关注点没有做到分离,增大了编码复杂度。举个例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int ret = register();// 注册用户
if (ret == -1){ // 用户名不合法
   // 提示用户名不合法 
}else if(ret == -2){ // 手机号不合法
   // 提示重新输入手机号
}else if(ret == -3){ // 写入DB失败
   // 重试
}

通过上面例子发现,错误码既负责了描述当前注册失败的原因,又控制了代码分支(if else),实际上随着业务发展错误原因不断增多,还可能邮箱不合法、证件号不合法,错误数量将会远远多于3个,代码中需要大量的if else,乱且不好维护。

谷歌/微信APIV3RPC错误模型如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package google.rpc;

message Status {
  // A simple error code that can be easily handled by the client. The
  // actual error code is defined by https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
  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:错误码,谷歌一共定义了16个错误码,不允许自定义。谷歌建议认为让开发人员编写用于处理大量错误逻辑的代码很不友好,建议每个 接口可能返回的错误码不超过3 个。

message:面向开发人员的错误描述。 它既应说明错误,又应提供可行的解决方案,特别注意,谷歌强调错误消息不属于 API 协议,它们随时都会更改,应用代码不得严重依赖于错误消息。在编写错误消息时请考虑以下准则:

  • 不要假设用户是您 API 的专家用户。用户可能是客户端开发人员、操作人员、IT 人员或应用的最终用户。
  • 不要假设用户了解有关服务实现的任何信息,或者熟悉错误的上下文(例如日志分析)。
  • 如果可能,应构建错误消息,以便技术用户(但不一定是 API 开发人员)可以响应错误并改正。
  • 确保错误消息内容简洁。如果需要,请提供一个链接,便于有疑问的读者提问、提供反馈或详细了解错误消息中不方便说明的信息。此外,可使用详细信息字段来提供更多信息。

details:客户端代码可用于处理错误的其他错误信息,Google API 为错误详细信息定义了一组标准错误负载, 涵盖了对于 API 错误的最常见需求,例如配额失败和无效参数。与错误代码一样,开发者应尽可能使用这些标准载荷,并且只有在可以帮助应用代码处理错误的情况下,才应引入其他错误详细信息类型,若错误信息只能由人工处理,则应根据错误消息内容让开发人员手动处理,而不是引入其他错误详细信息类型。

谷歌HTTP返回模型和RPC由微小区别:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// The error schema for Google REST APIs. NOTE: this schema is not used for
// other wire protocols.
message Error {
  // This message has the same semantics as `google.rpc.Status`. It has an extra
  // field `status` for backward compatibility with Google API Client Library.
  message Status {
    // This corresponds to `google.rpc.Status.code`.
    int32 code = 1;
    // This corresponds to `google.rpc.Status.message`.
    string message = 2;
    // This is the enum version for `google.rpc.Status.code`.
    // 注意看注释,谷歌认为该字段应该是废弃掉,之所以存在是为了兼容
    google.rpc.Code status = 4;
    // This corresponds to `google.rpc.Status.details`.
    repeated google.protobuf.Any details = 5;
  }
  // The actual error payload. The nested message structure is for backward
  // compatibility with Google API client libraries. It also makes the error
  // more readable to developers.
  Status error = 1;
}

阿里巴巴错误码规范:

阿里巴巴对外的文档各不一致,这里选择最广为人知的《阿里巴巴JAVA开发规范》

1、【强制】错误码不能直接输出给用户作为提示信息使用。 说明:堆栈(stack_trace)、错误信息(error_message)、错误码(error_code)、提示信息(user_tip)是一个有效关联并互相转义的和谐整体,但是请勿互相越俎代庖。

2、【强制】服务端发生错误时,返回给前端的响应信息必须包含 HTTP 状态码,errorCode、 errorMessage、用户提示信息四个部分。 说明:输出给用户的提示信息 要求:简短清晰、提示友好,引导用户进行下一步操作或解释错误原因,提示信息可以包括错误原因、上 下文环境、推荐操作等。errorMessage:简要描述后端出错原因,便于错误排查人员快速定位问题,注意不要包含敏感数据信息。

注意: 1)阿里巴巴和谷歌协议完全相反,阿里巴巴认为错误码和httpcode无关,但是谷歌错误码和httpcode是多对一的关系。 2)阿里巴巴规范中明确定义了user_tip是面向用户,error_message是面向开发者,但是谷歌协议中未对面向用户的user_tip进行单独定义。

微软:

windowsAPI完全是另一种思路,举例说明:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//函数
BOOL DeviceIoControl(
  HANDLE       hDevice,
  DWORD        dwIoControlCode,
  LPVOID       lpInBuffer,
  DWORD        nInBufferSize,
  LPVOID       lpOutBuffer,
  DWORD        nOutBufferSize,
  LPDWORD      lpBytesReturned,
  LPOVERLAPPED lpOverlapped
);

//返回值
If the operation completes successfully, the return value is nonzero.
If the operation fails or is pending, the return value is zero. To get extended error information, call GetLastError.

微软并不知直接返回错误码,而是仅返回成功失败,如果开发者关注错误码则可以调用GetLastError函数获取错误码以及错误信息。

问题二:错误码重叠问题

举一个错误码重叠导致严重问题的例子: 假设A服务是给用户发放红包,A依赖B服务,B服务-1错误码表示用户无权限领取红包,但是A服务-1的错误码表示该用户已经领取,如果A服务开发者未对B服务的错误码的进行转移处理,直接抛出错误码导致A的调用方逻辑判断错误。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// A服务代码如下
int ret = B::fun();
if(ret){
   return ret;
}

分析上面例子其实是由两个问题导致的: 1)不同服务相同的错误码表示不同的错误; 2)未对领域外的错误码进行收敛;

针对第一点:

谷歌:

上面已经讲过,谷歌错误码只有16个,并且严格定义了每个错误码表示的错误类型,因此不存在错误码重叠的情况。

阿里:

1、【强制】编号不与公司业务架构,更不与组织架构挂钩,以先到先得的原则在平台申请, 审批生效,编号即被永久固定。 2、【强制】错误码使用者避免随意定义新的错误码

其它:

也了解到一些公司与阿里完全相反,错误码与业务架构、服务强绑定,以登录失败为例,不同的组织架构、相同组织架构不同的服务均使用不同的错误码。与阿里巴巴规范相比:一个错误码可以唯一定位到一个服务的一类错误,优点是在长链路(尤其是跨业务、跨服务情况下)使用错误码定位问题更高效,缺点是这种情况需要定义大量的错误码,错误码很难有自解释性。

针对第二点,参考各个规范,认为: 1)领域内可以不收敛错误码,但是在跨领域时一定要收敛错误码,不允许把其他领域的错误码直接返回上层服务,参考谷歌规范每个接口收敛至不超过3个为宜。 2)调用组件、公共库等返回的错误码,务必收敛为业务相关的错误码。例如注册接口不应该把DB写入失败错误码返回,而是转译为注册失败。

问题三:错误码细分粒度不统一

错误码过细:

错误码定义过细过多、过度随意,将会导致调用方对错误处理的逻辑复杂,无法很好的对错误码进行转义或收敛。以登录接口为例:手机号不合法、账号不合法、密码太简单、验证码错误应统一收敛为参数错误,而不应该每种情况定义一个错误码。

错误码过粗:

若随意复用错误码、错误码拆分不细、错误码过度收敛等情况,将会导致调用方无法准确和正确处理错误或给用户提示。比如注册时需要先查询用户是否存在,读取DB失败和用户已存在应该使用不同的错误码,因为读取DB失败可通过重试解决,用户已存在则不允许用户注册,是两个完全不同类型的错误,一个窍门就是收敛后的错误码只能表示参数错误、逻辑错误、系统错误中的一类。

未完待续…..

下次再来讨论: 错误码无类型划分问题 字母or数字 后台与前端/小程序、后台与后台错误信息如何定义和传递 面向传递、面向日志、面向用户时该如何处理

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
错误码与错误提示设计:最佳实践与资源指南
在软件开发的复杂世界中,错误是不可避免的。无论是因为外部系统的变化、用户输入的错误,还是内部逻辑的缺陷,错误都会出现。为了有效管理这些错误,并向用户和开发者提供清晰、有用的反馈,设计一套合理的错误码和错误提示系统变得至关重要。本文将探讨设计错误码和错误提示的最佳实践,并介绍一些可供参考的开源规范和模板。
运维开发王义杰
2024/04/15
1K0
错误码与错误提示设计:最佳实践与资源指南
gRPC: 如何设计 RPC 错误码?
我们介绍 rk-boot 库,一个快速启动 GRPC 的企业级 golang 微服务框架。
尹东勋
2021/09/28
2.5K0
gRPC: 如何设计 RPC 错误码?
Go - 统一定义 API 错误码
errno.ErrUserPhone、errno.OK 表示自定义的错误码,下面会看到定义的地方。
新亮
2021/01/05
1.3K0
Echo 框架: RPC 错误码设计
通过 rk-boot ,用户可以轻松搭建 Echo 框架微服务,rk-boot 集成了 Panic 捕捉以及标准错误类型。
尹东勋
2021/11/02
8610
Echo 框架: RPC 错误码设计
Gin 框架: RPC 错误码设计
通过 rk-boot ,用户可以轻松搭建 Gin 框架微服务,rk-boot 集成了 Panic 捕捉以及标准错误类型。
尹东勋
2021/10/28
1.5K0
Gin 框架: RPC 错误码设计
GoFrame 框架: RPC 错误码设计
本文通过一个完整的例子,介绍如何在 GoFrame 框架下设计合理的 API 错误码。
尹东勋
2021/12/22
7530
GoFrame 框架: RPC 错误码设计
gorilla/mux 框架(rk-boot): RPC 错误码设计
本文通过一个完整的例子,介绍如何在 gorilla/mux 框架下设计合理的 API 错误码。
尹东勋
2022/02/15
6090
gorilla/mux 框架(rk-boot): RPC 错误码设计
0187eaia data access error_文档错误码700015
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/09/30
1.6K0
Go语言错误码设计与管理实践
最近在做一个和前端、第三方平台(可以简单理解为公司别的部门或者客户软件)直接交互的服务,涉及到用户注册、登录、数据处理等模块。架构图大概如下:
xin猿意码
2023/10/18
8750
Go语言错误码设计与管理实践
API网关 APIG,调用已发布的API,错误码0605
在通过API网关开放电话号码归属地查询服务前,您需要获取登录华为云控制台的用户名和密码,并确保已实名认证此用户。同时,您还需要获取如表1所示信息。
玖柒的小窝
2021/09/19
2K0
钉钉E应用开发踩过的小坑之钉钉官网有两个全局错误码链接,啥区别??
https://open-doc.dingtalk.com/microapp/serverapi2/npfg02这是一个含错误码和说明(我一直看的是这个全局错误码,只看说明的话满脑子是问号啊 O(∩_∩)O哈哈~)
全栈程序员站长
2022/08/15
3.7K0
优雅地进行全局异常处理、统一返回值封装、自定义异常错误码——Graceful-Response推荐
Graceful Response是一个Spring Boot体系下的优雅响应处理器,提供一站式统一返回值封装、全局异常处理、自定义异常错误码等功能,使用Graceful Response进行web接口开发不仅可以节省大量的时间,还可以提高代码质量,使代码逻辑更清晰。
用户2865443
2023/11/09
3.1K0
蚂蚁区块链第17课 错误码指导大全
本文介绍蚂蚁区块链的错误码按出错来源分为5类:平台校验错误码、虚拟机错误码、区块链错误码、客户端系统错误码、TEE 错误码,并给出了具体的错误码值和解释说明。
辉哥
2019/04/18
1.8K0
领域服务上抛异常还是返回错误码
在 C 语言中,错误码的返回方式有两种:一种是直接占用函数的返回值,函数正常执行的返回值放到出参中;另一种是将错误码定义为全局变量,在函数执行出错时,函数调用者通过这个全局变量来获取错误码
码农戏码
2022/06/07
8010
微信企业号根据错误码返回错误信息类封装
微信开发中返回错误码每次需要查询错误返回码文档才知道具体的错误信息(查看返回的errormsg也可知道),因此封装一个错误码返回的类来查看!
全栈程序员站长
2022/08/14
9490
【最佳实践】巡检项:对象存储(COS)400 状态码
可以通过对应返回body的Message信息来确定问题的原因,如下示例报错原因为请求参数不符合要求
xinjwang王健
2022/04/07
3K0
腾讯会议API错误码200003定位分析
腾讯会议(Tencent Meeting,TM)Rest API 是为参与腾讯会议生态系统建设的合作方开发者接入并访问腾讯会议资源提供的一组工具,是访问腾讯会议 SaaS 服务的入口。合作伙伴可以通过腾讯会议API 进行二次开发,例如创建一个会议,修改会议,查询会议信息等。
yukine
2020/11/04
2.8K0
腾讯会议API错误码200003定位分析
Go 进阶训练营 – Go 工程化实践二:API 设计
为了统一检索和规范 API,B站内部建立了一个统一的 bapis 仓库,整合所有对内对外 API。
Yuyy
2022/10/04
1.1K0
Go 进阶训练营 – Go 工程化实践二:API 设计
如何设计API返回码(错误码)?
—1— 前言 客户端请求API,通常需要通过返回码来判断API返回的结果是否符合预期,以及该如何处理返回的内容等。 相信很多同学都吃过返回码定义混乱的亏,有的API用返回码是int类型,有的是string类型,有的用0表示成功,又有的用1表示成功,还有用“true”表示成功,碰上这种事情,只能说:头疼。 API返回码的设计还是要认真对待,毕竟好的返回码设计可以降低沟通成本以及程序的维护成本。 —2— HTTP 状态码 以HTTP状态码为例,为了更加清晰的表述和区分状态码的含义,HTTP状态做了分段。 对于
玄姐谈AGI
2022/03/03
8860
如何设计API返回码(错误码)?
客户端请求API,通常需要通过返回码来判断API返回的结果是否符合预期,以及该如何处理返回的内容等
KenTalk
2020/08/02
6.6K0
相关推荐
错误码与错误提示设计:最佳实践与资源指南
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验