厂商业务码 → canonical 错误类型的码表(designs/provider-reliability.md §1;
照搬 Keelson Providers/ProviderBusinessCodes.cs + ChatProviderException.RefineKind)。
为什么要有这张表:限流和欠费在 HTTP 上常常是同一个 429(OpenAI 兼容的
insufficient_quota 就这么干),光看状态码会把「再等一会就有」当成「再等一个月也没有」,
ChatModel 于是对欠费反复退避重试。反过来,欠费被回成 400 时只看状态码会判成参数错。
状态码只给初判,业务码说了算。
判定次序(refine-error,只会「收紧」):
error.type / error.code / 顶层 code / MiniMax base_resp.status_code)→ 定;
provider 专属行优先于通用行;码表是数据(不是 if 链):补新样本往 rules 加一行即可,判定次序不用动。
厂商业务码 → canonical 错误类型的码表(designs/provider-reliability.md §1; 照搬 Keelson `Providers/ProviderBusinessCodes.cs` + `ChatProviderException.RefineKind`)。 **为什么要有这张表**:限流和欠费在 HTTP 上常常是同一个 429(OpenAI 兼容的 `insufficient_quota` 就这么干),光看状态码会把「再等一会就有」当成「再等一个月也没有」, ChatModel 于是对欠费反复退避重试。反过来,欠费被回成 400 时只看状态码会判成参数错。 **状态码只给初判,业务码说了算。** 判定次序(`refine-error`,只会「收紧」): 1. 码表命中(`error.type` / `error.code` / 顶层 `code` / MiniMax `base_resp.status_code`)→ 定; provider 专属行优先于通用行; 2. 402 → 欠费; 3. 原判是 :validation-error / :provider-error 且文案像「上下文超长」→ :context-overflow-error; 4. 原判是 auth / validation / rate-limit → 维持(**文案绝不凭空造出限流,也不把限流改成欠费**); 5. 其余(5xx / provider)文案像欠费 → :quota-exhausted-error。 码表是数据(不是 if 链):补新样本往 `rules` 加一行即可,判定次序不用动。
(body-codes body)从错误正文挖出 {:type :code}:OpenAI 兼容 {:error {:type :code}}、{:error "code"}、
智谱顶层 code、MiniMax base_resp.status_code。
从错误正文挖出 {:type :code}:OpenAI 兼容 `{:error {:type :code}}`、`{:error "code"}`、
智谱顶层 `code`、MiniMax `base_resp.status_code`。(body-error provider body)HTTP 200 里的业务错(MiniMax / 智谱风格 base_resp.status_code ≠ 0)→ canonical error;正常 → nil。
HTTP 200 里的业务错(MiniMax / 智谱风格 `base_resp.status_code ≠ 0`)→ canonical error;正常 → nil。
(classify provider type code)业务码 / error.type → 错误类型;不在表里 → nil。provider 专属行优先于通用行;type 先于 code。
业务码 / error.type → 错误类型;不在表里 → nil。provider 专属行优先于通用行;type 先于 code。
(classify-body provider body)正文里的业务码 → 错误类型(只看码;文案留给 refine-error)。
正文里的业务码 → 错误类型(只看码;文案留给 `refine-error`)。
(extract-message body)从错误正文挖人话:{:error {:message}}、{:error "…"}、{:msg}(智谱)、{:message}、
{:base_resp {:status_msg}}(MiniMax)。挖不到 → nil。
从错误正文挖人话:`{:error {:message}}`、`{:error "…"}`、`{:msg}`(智谱)、`{:message}`、
`{:base_resp {:status_msg}}`(MiniMax)。挖不到 → nil。(normalize-provider provider)provider 名 → 码表里的家族(各家把同一个服务写成不同名字)。nil / 空 → "openai"(OpenAI 兼容那套词)。
provider 名 → 码表里的家族(各家把同一个服务写成不同名字)。nil / 空 → "openai"(OpenAI 兼容那套词)。
(refine-error err body)按正文的业务码 / 文案收紧一个已按状态码分好类的 canonical error(判定次序见 ns 文档)。
body 可以是 map 或字符串;provider 取 err 的 :provider。
按正文的业务码 / 文案收紧一个已按状态码分好类的 canonical error(判定次序见 ns 文档)。 `body` 可以是 map 或字符串;provider 取 err 的 :provider。
(retry-delay-text text)正文 / 消息里的 try again in 1.5s / try again in 200ms → 毫秒;没有 → nil(A-35)。
正文 / 消息里的 `try again in 1.5s` / `try again in 200ms` → 毫秒;没有 → nil(A-35)。
[provider-家族-或-nil code 错误类型]。provider 为 nil = 各家通用(OpenAI 兼容的那套词)。 来源:Keelson ProviderBusinessCodes.cs(A-20 / A-29)。
[provider-家族-或-nil code 错误类型]。provider 为 nil = 各家通用(OpenAI 兼容的那套词)。 来源:Keelson ProviderBusinessCodes.cs(A-20 / A-29)。
(stream-error provider error-obj)流内错误帧(Anthropic event: error 的 {:type :message}、OpenAI 系 {:error {...}})→ canonical error。
先按 error.type 初判,再过码表 / 文案收紧。未知 type 按服务端错(可重试)。
流内错误帧(Anthropic `event: error` 的 `{:type :message}`、OpenAI 系 `{:error {...}}`)→ canonical error。
先按 error.type 初判,再过码表 / 文案收紧。未知 type 按服务端错(可重试)。cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |