错误码概述:什么是错误码,错误码的作用与分类
我们每天都在跟各种错误打交道。页面崩了、接口超时、数据对不上……
你有没有想过——
为什么这些报错信息有的是一串数字,有的是一串字母加数字?为什么有的错误看一眼就知道原因,有的得翻半天文档?
这就是错误码的学问。我做了十几年开发和调试,踩过无数坑,今天把我的经验跟你聊聊。
什么是错误码
错误码,说白了就是一套标准化的故障编号系统。
你想想看,如果没有错误码,服务端给客户端返回一个「系统异常」,你能知道是哪块出问题了吗?连从哪开始查都不知道。
错误码像是一个病历编号。医生看到"ICD-10: J18.9",就知道这是"未特指的肺炎"。同样,开发看到"ERR_50001",就知道这是"数据库连接池耗尽"。
错误码的作用
我刚开始做项目时,觉得错误码就是个鸡肋。随便返回个"0"表示成功,"1"表示失败,够用了吧?
直到有一次线上事故。我们有个支付服务,对账时发现几万笔订单状态对不上。排查了一天,发现是某个接口在超时场景下返回了通用错误码,没人知道具体是哪步超时了。
那天我改了一宿的代码,把错误码从2个扩充到37个。从此再也不敢小瞧它了。
错误码到底能干嘛?我总结三个核心作用:
- 快速定位 —— 看到错误码,脑子里立刻映射到代码位置或日志上下文。
- 标准化沟通 —— 前端、后端、测试、运维用同一套编码沟通,不用再说"就是那个登录页面转圈半天的错误"。
- 自动化处理 —— 监控系统可以根据错误码自动告警、降级、恢复。我见过一个团队把错误码直接接入自动重启策略,效果出奇好。
| 作用 | 说明 | 我踩过的坑 |
|---|---|---|
| 快速定位 | 通过错误码直接找到对应模块和代码段 | 曾经把三个不同模块的错误码混用,排查花了2天 |
| 标准化沟通 | 统一术语,降低跨团队协作成本 | 前端说"白屏了",后端说"内存溢出了",其实是同一个问题 |
| 自动化处理 | 监控、告警、熔断、降级等自动化操作 | 我们后来写了个脚本,根据错误码频率自动调整限流阈值 |
错误码的分类
错误码怎么分?我一般从两个维度切:严重程度和来源。
按严重程度分类
- Info(信息) —— 不是错误,只是提醒。比如"当前请求被限流,降级为缓存数据"。我习惯用 1xx 或 2xx 前缀。
- Warning(警告) —— 系统还能跑,但需要注意。比如"磁盘使用率超过85%"。用 3xx 前缀。
- Error(错误) —— 功能不可用,需要人工介入。比如"数据库连接超时"。用 4xx 或 5xx 前缀。
- Fatal(致命) —— 整个进程或服务不可用,可能触发重启。比如"堆内存溢出 OOM"。用 6xx 或 9xx 前缀。
按来源分类
| 来源 | 举例 | 典型前缀 |
|---|---|---|
| 客户端 | 参数校验失败、权限不足 | CLI_ERR_ |
| 服务端 | 业务逻辑异常、数据库故障 | SRV_ERR_ |
| 网络层 | 连接超时、DNS解析失败、TLS握手失败 | NET_ERR_ |
| 第三方 | 调用的外部API返回异常 | EXT_ERR_ |
为什么要按来源分?
你想想看,线上出问题,让后端去排查网络层错误,那不是浪费时间吗?
我参与过一个团队,错误码根本没有来源信息。有一次连续收到"ERR_5003",后端查了半天发现是前端SDK版本过旧导致的。如果用了CLI前缀,一下子就能把问题丢给前端团队。
典型错误码结构
一个规范的错误码应该包含三部分:
前缀 + 数字编号 + 简要描述
例子:
SRV_ERR_0501 -> 服务端-错误-用户不存在
NET_WARN_2003 -> 网络层-警告-连接超时重试成功
我建议前缀用大写字母和下划线,数字编号用4位数字(前两位模块,后两位具体错误)。这样一眼就能看出模块归属。
错误码处理的核心流程
我们来看看错误码在调试过程中是怎么流转的。下面这张图我把核心节点画出来了:
这张图很直白:代码报错 → 生成错误码 → 记到日志 → 抓包捕获 → 最后定位。每一步的错误码信息都在帮助你收窄问题范围。
现实中的经验
有一次我做远程调试,客户那边报了一个错误码"ERR_8001",我查了所有文档都找不到这个码。后来发现是他们自己私自加的错误码,没纳入统一管理。
自那以后,我强制要求团队必须把所有错误码登记在一个共享表格里,并且代码里加个自动校验:如果抛出的错误码不在白名单里,直接打印警告并带上建议码。
错误码的设计没有银弹。但如果你能搞清楚「什么是错误码」、「它解决什么问题」、「怎么分才好用」,至少不会在线上出大乱子。
嗯,这一章先聊到这儿。记住:好的错误码能帮你节省90%的排查时间。坏的错误码……会让你想砸键盘。