Skip to main content

错误码

平台的错误由两个正交维度描述:业务 code(回答”具体是什么问题”)与 HTTP 状态码(回答”这类问题归哪一类”)。这一页穷举全部业务 code 并写清两者的换算规则。

响应封套

所有接口返回同一形状:
code === 0 表示成功。非 0 即失败,此时 datanull
判断失败必须同时看 HTTP 状态与 code,即 !response.ok || body.code !== 0单看 HTTP 不够:某些历史路径可能返回 2xx 携带非 0 code。单看 code 也不够:代理层或鉴权层返回的 HTML 错误页根本没有 code 字段。解析响应体时先读文本再 parse,不要写 .json().catch(() => null)——那会把”返回了非 JSON”这个关键真相吞掉,留给你一个无从下手的空对象。

HTTP 状态推导规则

业务 code 不等于 HTTP 状态。服务端按以下规则推导(deriveHttpStatusFromCode):
关键不变式:抛出的错误永远不会以 HTTP 2xx 返回这条规则是被一次线上事故换来的。曾经 AppError.statusCode 默认 200,所有只传两个参数的业务错误都以 HTTP 200 + 非 0 code 返回,前端封套只能靠 code 判失败,message 一旦为空就退化成自相矛盾的 Request failed: 200现在有两道保险:构造时按 code 推导状态,全局错误处理器再校验一次——statusCode < 400 就重新推导。message 也有非空兜底(回落 请求失败)。
未捕获的非 AppError 异常统一返回:
message 被刻意脱敏,不透出内部堆栈。要定位得靠服务端日志的 [unhandled] 记录(含 method 与 path)。

全部错误码

认证与账号

短信与人机校验

后两个是配置问题不是用户问题:见到它们说明服务端缺凭证,重试无用。

文件与存储

FILE_TYPE_MISMATCHFILE_TYPE_NOT_ALLOWED 是两件事:前者是扩展名与真实 MIME 不符(把 .exe 改名成 .png 会命中),后者是这个类型压根不在白名单。 具体限额见 限额表

技能市场

任务

TASK_ALREADY_PAID 用 409 而不是 200 是刻意的:“已经支付过”是状态冲突,不是成功。用 2xx 会让全局处理器给一个抛出的错误发 2xx,直接违反上面的不变式。客户端可以把 409 当作幂等信号处理——重复提交支付时它意味着”你要的结果已经达成”,但你仍应按失败分支走,而不是当作本次调用成功。

API Key

充值

RECHARGE_AMOUNT_MISMATCH 出现在支付回调链路,意味着渠道回传金额与订单不符——这是风控信号,不要自动重试,应人工核查。

积分消费

CONSUME_MODEL_RATE_ZERO 说的是模型没配这种计费单位的费率(比如按秒计费的模型收到了 token 计费请求),不是余额问题。见 计费公式

订阅与团队

积分账户

支付

PAY_NOTIFY_VERIFY_FAILEDPAY_NOTIFY_SERVICE_NOT_ALLOWED 是安全边界被触碰的信号,不是普通业务失败。它们出现在你的日志里意味着有人向回调端点发了未通过验签或指向非白名单服务的请求。

发票

开票期限 60 天是硬编码的业务规则,不是可配项。

礼品卡

这一组包含平台上仅有的五位域码
五位码存在的原因:兑换失败有七种不同原因(不存在 / 无效 / 已兑换 / 过期 / 冻结 / 批次领完 / 达到上限),全部映射到 HTTP 400 会让客户端无法区分该提示什么。所以业务码保留区分度,HTTP 状态按前缀归类。这正是”业务 code 与 HTTP 状态是两个维度”的最好例证——HTTP 状态回答归类,业务 code 回答具体。你的兑换页应该 switch 五位码给出不同文案,而不是统一显示”兑换失败”。

基础设施

503唯一明确可重试的错误码。其余 5xx 重试前应先确认不是配置或数据问题。

Agent 调用特有的错误

/v1/* 的调用链路上还有几个不走 ResponseCode 的错误形态:
trialExhausted 必须单独识别。把它归进”当前操作被拒绝”这类通用兜底,用户会以为账号出了问题——实际只是试用轮次用完了,正确的引导是去购买页而不是找客服。

错误处理范式

流式接口(SSE)的错误处理有个额外陷阱:在 httpxstream() 上捕获 HTTPStatusError 时,必须先 await exc.response.aread() 才能读 body,否则抛 StreamNotRead 把真实错误覆盖掉。

按状态分类的处理建议

关于 404 与 403:跨用户访问他人资源时平台通常返回 404 而非 403。原因是 403 会泄露”这个 ID 确实存在”,让资源变得可枚举。所以拿到 404 不代表 ID 写错了,也可能是这个 ID 不属于你。

相关页面

端点速查

全部 /v1/* 端点

SSE 事件

流式响应的事件类型

认证

API Key 与鉴权

限额表

触发 429 的具体阈值
核对日期 2026-08-11。来源:services/core/src/constants/response-code.ts(全部业务码)、services/core/src/errors/app-error.tsderiveHttpStatusFromCode)、services/core/src/errors/error-handler.ts(全局处理器)。