所有接口的响应统一为 ResponseDTO 包装:
{
"code": 0,
"ok": true,
"msg": "操作成功",
"data": { ... }
}
失败时:
{
"code": 200301,
"ok": false,
"msg": "签名验证失败",
"data": null
}
code = 0 表示成功;非 0 表示业务错误,HTTP 状态码可能仍为 200。判断成功请用 code === 0 或 ok === true,不要只看 HTTP status。
| 段位 | 类别 | 说明 |
|---|---|---|
| 200001-200099 | AUTH | API Key 相关 |
| 200101-200199 | RATE_LIMIT | 限流 / IP |
| 200201-200299 | PERMISSION | 权限 / 资源不存在 |
| 200301-200399 | SIGN | 签名 / 时间戳 |
| 200401-200499 | BIZ | 业务(应用、参数等) |
| 200501-200599 | BIZ | 下载令牌 |
| 200601-200699 | WEBHOOK | Webhook |
| 200701-200799 | BIZ | 帖子 / 批量 |
| 200801-200899 | PROXY | 用户代理 |
| 200901-200999 | INTERNAL | 内部网关 / OAuth |
完整字典在 错误码字典 页面,可按分类筛选 / 搜索。后端会同步维护,错误码上线即可查。
async function callApi<T>(call: () => Promise<{ code: number; msg: string; data: T }>) {
const res = await call()
if (res.code === 0) {
return res.data
}
switch (res.code) {
case 200001:
case 200002:
case 200003:
throw new AuthError(res.msg) // 应用层重新申请 Key
case 200101:
case 200102:
throw new RateLimitError(res.msg) // 退避重试
case 200301:
case 200302:
throw new SignError(res.msg) // 检查时钟 / 签名实现
case 200201:
case 200203:
throw new PermissionError(res.msg) // 申请权限 / 提示用户
default:
throw new ApiError(res.code, res.msg)
}
}
每个请求都有 X-Request-Id 响应头。把它和你的业务日志关联,反馈给平台时附带,可以最快定位问题。
code,不要假设 HTTP 200 = 业务成功msg 直接展示给终端用户,做映射或本地化Q:为什么 HTTP 返回 200,但接口其实失败了?
平台用统一的 ResponseDTO 承载业务结果,业务错误通过 code(非 0)表达,HTTP 状态码仍可能是 200。判断成功只看 code === 0 / ok === true。
Q:code 和 msg 哪个适合做程序分支?
用 code(稳定的数值契约)做分支;msg 是面向人的描述,文案可能调整,不要用于逻辑判断。
Q:遇到没列在文档里的错误码怎么办?
错误码字典实时同步后端,可按分类筛选 / 搜索。仍无法定位时,带上响应头里的 X-Request-Id 反馈给我们,便于按请求链路排查。
Q:自动重试会不会造成重复下单 / 重复发帖? 会。任何带副作用的写操作都要做幂等(业务唯一键 + 去重缓存),尤其是限流退避重试场景,详见最佳实践。