🌍 译介 · 编译自 Nordic APIs

好的 API 错误,是开发者最好的朋友

错误码几乎是你在 API 响应里最不想见到的东西,但它又极其有用——它是开发者向用户传达「哪里错了、为什么、怎么修」的唯一稳定通道。本文编译自 Nordic APIs《Best Practices for API Error Handling》(2017-06-15,作者 Kristopher Sandoval),拆解 HTTP 状态码 1XX–5XX、好/坏错误码的三个标准,并结合 RFC 7807 / RFC 9457 Problem Details 给出可直接套用的结构化错误模板。

📅 更新于 2026-07-24 ⏱ 约 10 分钟阅读 🏷 译介
免费试用 YesApi Pro 查看全部定价 →
🌐本文由 YesApi Pro 团队编译Nordic APIs 的文章《Best Practices for API Error Handling》,原作者 Kristopher Sandoval(原文发布于 2017-06-15)。版权归原作者所有,内容仅供学习参考。查看英文原文 →
📌 核心结论
好错误码 = 正确 HTTP 状态码 + 内部参考 ID + 人话可读信息(说清原因与修法)。永远别只回一个裸 400。4XX 是客户端责任、5XX 是服务器责任,用最具体的码(如 422 而非笼统 400)。新项目直接采用 RFC 9457(Problem Details)标准结构:type/title/status/detail/instance,让机器可解析、让人可读。
📑 本文目录
  1. 错误码的价值
  2. HTTP 状态码 1XX–5XX
  3. 好错误码的三个标准
  4. 给上下文 + 人话可读
  5. 大厂范例:Twitter/Facebook/Bing/Spotify
  6. 结构化标准:RFC 7807 / 9457
  7. 结论与落地
01

一、错误码的价值

错误码像打针——不愉快,但极有用。它是 API 响应阶段开发者向用户传达失败的基本方式,也是错误发生后启动排查的第一步

用户无法选择何时出错、错在哪;错误响应因此成了出错时唯一「恒定、一致」的沟通通道。一个好错误码同时完成两件事:澄清现状 + 传达本该怎样用。例如 401 Unauthorized – Please Pass Token,既点明「未授权」,又告诉用户「本接口需要传 token」——花极少数据量,却价值巨大。

02

二、HTTP 状态码 1XX–5XX

虽说有其他协议,但 HTTP 状态码主导了 API 沟通,厂商自定义码也大多从这套区间派生。理解区间含义,等于知道了「错在谁身上」:

区间含义责任方典型码
1XX信息/协议状态100 Continue、101 Switching Protocols
2XX成功200 OK、201 Created、202 Accepted
3XX重定向/资源位置变了301 Moved Permanently
4XX客户端错误客户端400、404、414 URI Too Long、429 Too Many Requests
5XX服务器错误服务器502 Bad Gateway、503 Service Unavailable

关键区别:4XX 是客户端的锅(请求有问题),5XX 是服务器的锅(有效请求仍失败)。429 用于限流,414 提示 GET 数据太长该改 POST。

03

三、好错误码的三个标准

一个「真有用」的错误码必须满足三条:

  • 附 HTTP 状态码:让人立刻知道问题域与归属(4XX/5XX)。
  • 带内部参考 ID:便于内部文档/工单定位(如 BR0x0071);若参考表含状态码映射,它甚至可替代裸状态码。
  • 人话可读的信息:概括上下文、原因与大致解法。

400 Bad Request 只告诉你「客户端错了」,却不说错在哪——这是「看似功能、实则不功能」的典型。

04

四、给上下文 + 人话可读

光有机器码不够,得在响应体里给上下文。下面这个比裸 400 好,但仍差一口气——它只给了内部参考号,用户还得去查文档:

HTTP/1.1 400 Bad Request
Content-Type: application/json
{ "error" : "REQUEST - BR0x0071" }

稍加改造,既保留参考号又给可操作信息

HTTP/1.1 400 Bad Request
Content-Type: application/json
{ "error" : "Bad Request - Your request is missing parameters.
    Please verify and resubmit. Issue Reference Number BR0x0071" }

这下用户知道「参数缺失」,起码有了排查起点。记住:为机器编码 ≠ 为人编码,两者都要兼顾——状态码和参考号给机器,人话信息给人。

05

五、大厂范例:Twitter/Facebook/Bing/Spotify

Twitter400 + 自定义码 215 + 信息 Bad Authentication data——既说清原因,又给内部码备查。

Facebook Graph:返回 type: OAuthExceptioncode: 2500fbtrace_id,并明确指出「picture 字段重复定义」,还提示该行为在 2.1 前才允许——顺带沟通了版本变更。

Bing(最佳范例):code: 1001 + Message: Required parameter is missing + 点名缺失参数 SearchRequest.AppId + 附 HelpUrl 解决链接。机器可读码、人话摘要、错误定位、解决入口,四样齐全。

Spotify:5XX 罕见但真实存在。502 Bad Gateway 看似 opaque,价值在响应头与日志里的生产环境标记——让人判断是「网关/负载」问题而非外部因素。

06

六、结构化标准:RFC 7807 / 9457

各家错误体五花八门({error:...}{code,msg}{errors:[...]}),客户端得为每个 API 写专用解析逻辑。IETF 的 RFC 7807 后来演进为 RFC 9457(Problem Details for HTTP APIs),定义了标准错误结构,新项目应直接采用:

HTTP/1.1 422 Unprocessable Content
Content-Type: application/problem+json

{
  "type": "https://api.example.com/errors/invalid-input",
  "title": "Invalid Input Parameters",
  "status": 422,
  "detail": "The 'email' field must use user@domain.com format",
  "instance": "/users/registration/2026-05-28/8042",
  "errors": [
    { "detail": "must be a valid email address", "pointer": "#/email" }
  ]
}

五个标准字段:type(URI,定位错误类型)、title(稳定短摘要)、status(HTTP 码)、detail(本次具体说明)、instance(用于日志关联的请求标识)。扩展字段(如 errors 数组)可一次返回全部校验错误,避免「改一个、交一个、又报一个」的折磨循环。

07

七、结论与落地

错误响应是信息源:既要告知问题,也要给出解法。平衡可用性(人话)与简洁性(机器可解析),平衡点找对,威力巨大。

落地清单:① 用最具体的状态码(邮箱校验失败用 422 而非笼统 400);② 错误体带 type/title/status/detail;③ 写操作失败给 Retry-After(429/503);④ 生产环境绝不外泄堆栈/SQL;⑤ 全局异常处理器统一序列化,路由只管业务;⑥ 给每个错误附带 instance 关联 ID 便于排障。

译者实战注 落地建议与延伸

需要快速落地?

YesApi Pro 私有部署、源码交付、当天上线,帮您把方案变为现实。

立即预约演示 →

常见问题

正确 HTTP 状态码 + 内部参考 ID + 人话可读信息(说清原因与修法)。只回裸 400 是最常见反模式。

RFC 9457 是 RFC 7807(Problem Details)的演进版,完全向后兼容。新项目直接用 9457,已用 7807 的天然合规。

笼统的 400/500 剥离了有用信息,客户端无法自动决策(如 401 刷新 token、429 退避重试)。422 带字段级 detail 比 400 强得多。

YesApi Pro 网关层提供统一的错误码与结构化响应(含 traceId/请求标识),并支持按业务自定义错误类型,把 RFC 9457 式结构化错误直接落到开放平台。
📚

继续阅读