写业务代码时最烦的不是报错本身,而是提示信息只有一句 error,看不出是参数写错、key 没生效,还是根本就没连出去。这篇给一套从请求发出到响应回来的排查顺序,每步都有可验证的动作,照着走能把问题范围缩到一层。
写业务代码时最烦的不是报错本身,而是提示只有一句 error,看不出是参数写错、key 没生效,还是请求根本没连出去。这时候最容易干的事是反复换 key、反复重试,结果问题还在原地。这篇给一套从请求发出到响应回来的排查顺序,每一步都有能验证的动作,照着走能把问题范围缩到某一层,再动手改。
整体思路是先读全、再分层。读全是别只盯 error 这一个词,把响应体、状态码、请求标识都拿到手;分层是按参数、鉴权、网络三层逐级缩小范围,定位到具体哪一层再改。下面的顺序不要跳步,跳步最容易白折腾。
先读完整错误体,别只看 error 这一个词
很多平台在响应体里给了比 error 更细的错误码和出错字段名,只看那一句等于主动扔掉线索。先把原始响应体、HTTP 状态码、平台返回的请求标识一并打印出来,哪怕格式很乱也先原样存下来,再去看结构。
- 把原始响应体、HTTP 状态码、request-id 一起打出来,别自己拼一句「请求失败」就完事
- 用最小可复现请求复现,一条 curl 或几十行脚本就够,去掉业务里其他调用,确认不是被上游代码吞了异常
- 把响应结构和站内 OpenAI 兼容接口规范对一遍,确认字段层级没读错,比如把嵌套的 error.message 当成了顶层字符串
参数层:结构、类型和必填项逐一核对
参数层的错误通常最容易被提示出来,但前提是你看得懂提示。参数校验失败一般会告诉你哪个字段不合格,而结构写错、类型写反可能只给一句笼统的失败。所以先按字段名、层级、类型三项过一遍,再怀疑别的。
- 核对字段名与层级对照接口文档检查大小写、是否多包了一层对象、数组和字符串有没有写反,字段名差一个字母就是两种结果。
- 检查必填项与枚举确认必填项没缺、枚举值没越界,消息数组最后一条的角色是否正确,这类问题返回的信息通常比较明确。
- 删到最小可用集再逐个加回不确定某字段该不该带就先删掉,请求能通之后一次加回一个,比一次塞满更容易定位是哪个字段惹的祸。
鉴权层:key、请求头和生效范围
鉴权报错的迷惑性在于提示都长得很像,但改法完全不同。是 key 本身无效、还是这个 key 没有目标模型的权限、还是额度或分组没开,这三种情况处理方式不一样。先用一个确定可用的最小请求验证 key,再往权限和额度方向查。
- 确认鉴权头写法与协议匹配,不同兼容层对 Authorization 的格式要求不完全一样,格式写错会直接落到鉴权失败
- 检查 key 是否被截断、有没有多余空格或换行,从环境变量读出来时带了引号或换行符也会出问题
- 分清 key 无效、无该模型权限、额度或分组没开这三类提示,别一看到鉴权失败就重新生成 key
| 现象 | 更可能在哪一层 | 先做的动作 |
|---|---|---|
| 提示字段名或类型不对 | 参数层 | 把字段删到最小集再逐个加回 |
| 明确说鉴权失败或未授权 | 鉴权层 | 用最小请求单独验证 key 是否可用 |
| 连接超时或根本没响应 | 网络与网关层 | 命令行直连,绕开框架和代理 |
| 响应到一半断开 | 网络与网关层 | 看超时设置和中间链路是否截断 |
网络与网关层:先确认请求真的发出去了
如果日志里连响应都没有,问题很可能在网络路径上,而不是代码参数。判断办法是绕开一切中间层,用命令行直连一次:能通,说明问题在你自己的代码或环境变量里;不通,再顺着代理、网关、容器网络一跳一跳往回找。
curl -v -H "Authorization: Bearer 你的KEY" -H "Content-Type: application/json" -d '{"messages":[{"role":"user","content":"ping"}]}' 你的接口地址- 先用命令行直连一次,绕开框架和代理,确认请求到底有没有发出去
- 逐步打开代理、网关、容器网络,每次只动一个变量,看是哪一跳吃掉了请求
- 区分连不上、连上没响应、响应到一半断掉这三种现象,它们的排查方向不一样
把这次排错变成下次能复用的记录
同一类报错在一个团队里往往会反复出现,原因就是每次排完就过去了,没人留下可复用的判断依据。把这次的关键信息固定记下来,下次遇到同类问题按清单走,能省掉大量重复试错。站内的错误码与状态说明页可以当对照表,具体条目到对应页面核对。
| 要记的项 | 为什么值得记 |
|---|---|
| 请求时间与目标地址 | 确认是持续失败还是某个时段的现象 |
| 状态码与错误码 | 下次一眼能归到参数、鉴权还是网络 |
| 耗时 | 区分慢和断,判断要不要动超时 |
| 改了什么之后通了 | 把有效动作沉淀成团队清单 |
记录之外还要回归:改完不只是一次通过,用固定几条用例把相关调用路径跑一遍,确认没把别的路径改坏。如果你在比较不同中转站的稳定性和错误率,可以先到站内的检测与评测页面看当时的数字,再决定要不要换线路。
下一步把这次的报错现象和分层结论对一遍站内接口规范与错误说明,让下次定位有据可依。→常见问题
报错只显示 error,什么都看不出来怎么办?
先把完整响应体和状态码打出来,很多平台在 body 里带更细的错误码和字段名,只是被日志截断或异常处理吞掉了。如果确实只有一句 error,就用最小请求逐步加参数来定位,观察从哪一步开始出错,比反复读那句提示有用得多。
同样的代码昨天能跑,今天报错了,是代码的问题吗?
先别改代码。按顺序排除三类变化:key 或额度状态有没有变、目标地址或网关有没有调整、网络和代理环境有没有动。这类「昨天还好」的报错,多数出在代码之外,先确认请求到底发到了哪里、对方回了什么。
怎么判断是参数写错还是鉴权没生效?
看返回的状态码和错误体指向哪一类:提示字段名、类型、必填项的基本是参数层;提示未授权、key 无效、无权限的基本是鉴权层;压根没有响应体的更可能是网络层。分不清时先发一个不带业务参数的最小请求,能通就说明鉴权没问题。