LiteLLM 错误体系 全链路文档¶
本系列文档完整描述 LiteLLM 的异常类型、上游 status_code 映射、Router 行为(cooldown/retry/fallback)、客户端可见信息、日志/监控可见点——从「日志里看到一行错」到「这是什么、为什么、谁该处理、影响范围、Router 会怎么自动反应」的全链路。
适用场景: - 运维排障:proxy 日志或 PaaS 告警里看到一个错误名,倒推根因与影响 - 开发:改 provider transformation 或 cooldown 逻辑前,先理解每条路径的语义 - SRE:判断"上游真的挂了"还是"用户输入错了",决定是否要紧急处理 - 接入新 provider:参考其它 provider 的 status_code 映射避免不一致
⚠️ 常见误解: -
APIConnectionError≠ "上游 5xx"——它的语义是 LiteLLM 这一端连不上 / 网络层错,Router 不会冷却走到它的 deployment。如果上游真的 502/503 被错误映射成APIConnectionError,Router 会持续往坏实例打。 -status_code≠ HTTP 实际状态——APIConnectionError.status_code硬编码为 500(exceptions.py:713),不是网络真实状态。 -BadRequestError不进 cooldown——400 类异常被认为是"用户错",不是 deployment 健康问题,Router 不冷却。 -Timeout走 408 不是 504——LiteLLM 本地超时映射到Timeout(status_code=408),跟上游真返 504 是两个不同的异常。
文档目录¶
| 文件 | 内容 |
|---|---|
| 01-exception-catalog.md | 25 个异常类全集:父类 / status_code / 何时抛 / message 长什么样 / 何处可见 |
| 02-provider-mapping.md | exception_mapping_utils.py 的跨 provider 映射矩阵(openai/azure/anthropic/vertex/bedrock/cohere/openrouter/vllm/together_ai/huggingface 等)+ 已知不一致 |
| 03-router-behavior.md | 每条异常的 Router 反应:是否 cooldown、是否 retry、RetryPolicy 自定义、fallback 怎么走、_should_retry 判定 |
| 04-where-to-see.md | 客户端看到的 JSON / proxy stdout 日志关键词 / S3 raw log / PaaS 告警字段 / Prometheus 指标 |
| 05-troubleshooting-by-symptom.md | 从症状倒推根因:用户报 X / 日志出现 Y / 监控涨了 Z → 看哪个异常、查哪里、要不要紧急处理 |
整体架构一览¶
flowchart TB
subgraph "上游 LLM"
Upstream["上游返回<br/>200 / 4xx / 5xx / 超时 / 断连"]
end
subgraph "Provider transformation 层<br/>litellm/llms/<provider>/"
ProvHandler["handle_error / transform_response<br/>抛出 provider 原生异常 或 httpx error"]
end
subgraph "异常映射层<br/>litellm_core_utils/exception_mapping_utils.py"
ExceptType["exception_type()<br/>:232<br/>按 custom_llm_provider 分支<br/>+ status_code 二级分支"]
TypedExc["litellm.<XxxError><br/>(25 种 LiteLLM 异常)"]
end
subgraph "Router 决策<br/>litellm/router.py"
ShouldRetry["_should_retry(status_code)<br/>utils.py:6526"]
Retry["重试 N 次"]
Cooldown["_set_cooldown_deployments<br/>(白名单见 cooldown_handlers.py:40-95)"]
Fallback["fallbacks 链<br/>切到下一个 model_group"]
Final["最终结果"]
end
subgraph "Proxy 层<br/>litellm/proxy/"
ProxyExc["ProxyException<br/>_types.py:3189<br/>转 OpenAI 兼容 JSON"]
HttpResp["HTTP 响应<br/>status_code + JSON body"]
end
subgraph "可观测性"
Stdout["proxy stdout 日志"]
S3["S3 raw log JSON"]
Prom["Prometheus<br/>litellm_deployment_cooled_down<br/>litellm_request_total{exception=...}"]
PaaS["PaaS 告警<br/>L3 / Level3"]
end
Upstream --> ProvHandler
ProvHandler --> ExceptType
ExceptType --> TypedExc
TypedExc --> ShouldRetry
ShouldRetry -- "True (408/409/429/5xx)" --> Retry
ShouldRetry -- "False (4xx 其它)" --> Cooldown
Retry -- 全失败 --> Cooldown
Cooldown --> Fallback
Fallback --> Final
Final --> ProxyExc
ProxyExc --> HttpResp
HttpResp --> Stdout
HttpResp --> S3
Cooldown -.写指标.-> Prom
Stdout -.告警规则.-> PaaS
style ExceptType fill:#fdd,stroke:#c33,stroke-width:2px
style TypedExc fill:#ffd,stroke:#aa3
style Cooldown fill:#fdd,stroke:#c33,stroke-width:2px
style ProxyExc fill:#dfd,stroke:#3a3
几点关键事实:
- 异常分两层:
litellm/exceptions.py是类型层(25 个类,每个有固定语义),litellm_core_utils/exception_mapping_utils.py是映射层(按 provider × status_code 决定抛哪个类)。运维看到的所有错误名都来自类型层;要改"507 该当 5xx 处理"这种事改映射层。 - Router 决策只看类型层:
_should_retry看status_code,cooldown 白名单看status_code+ message 字符串。所以映射层抛错才是决定 Router 行为的唯一入口——映射写错(如把 502 映射到APIConnectionError)会直接绕过 cooldown。 ProxyException重写 status_code:Proxy 层有几条特殊规则覆盖类型层的status_code,如No healthy deployment available一律转 429(_types.py:3221-3225)、tag routing 失败转 401。客户端看到的 status 不一定等于 LiteLLM 内部异常的 status。- 客户端只看到 OpenAI 兼容 JSON:所有 LiteLLM 异常都继承自
openai.XxxError,最终序列化成{error: {message, type, code, param}}给客户端。LiteLLM-specific 字段(llm_provider、litellm_debug_info、num_retries)拼在message里。 - S3 raw log 落库的是 standard_logging_payload:异常情况下
status字段 ="failure",error_information.error_class是 LiteLLM 异常类名,error_information.error_code是 status_code 字符串。详见 04-where-to-see.md。
速查:3 大类异常的 Router 行为¶
按 Router 反应快速归类(详细见 03-router-behavior.md):
| 大类 | 代表异常 | _should_retry |
进 cooldown 流程 | 典型语义 | 谁该处理 |
|---|---|---|---|---|---|
| 用户错 | BadRequestError / UnprocessableEntityError / PermissionDeniedError / ContextWindowExceededError / ContentPolicyViolationError |
❌ | ❌ | 请求 payload / 内容审核 | 调用方 |
| Deployment 健康问题 | AuthenticationError / NotFoundError / RateLimitError / Timeout / InternalServerError / ServiceUnavailableError / BadGatewayError |
✅(408/429/5xx) ❌(401/404 但仍 cooldown) |
✅ | 上游挂 / key 错 / 模型不存在 / 限流 | 运维 + 配置方 |
| LiteLLM 自身网络问题 | APIConnectionError |
❌(status_code=500 是假的) | ❌(被字符串白名单跳过) | 本地 DNS / TCP 连不上 | LiteLLM 部署环境 |
⚠️ 第 3 类是最容易踩坑的地方:上游 5xx 如果在 provider transformation 里被误抛成 APIConnectionError,Router 既不重试也不冷却,会反复打坏实例。这是真实发生过的 bug 类型,详见 02-provider-mapping.md §4 已知不一致。
决策树:你应该看哪一篇?¶
flowchart TD
Q{你的问题是?}
Q -->|"日志/告警里看到一个异常名,想知道它是什么"| A1[01-exception-catalog]
Q -->|"上游 X 状态码 LiteLLM 抛了什么、能不能换一种映射"| A2[02-provider-mapping]
Q -->|"为什么 Router 没自动避让 / 重试 / fallback"| A3[03-router-behavior]
Q -->|"客户端看到的 message 跟 proxy 日志对不上"| A4[04-where-to-see]
Q -->|"线上报错了, 我从哪儿入手排查"| A5[05-troubleshooting]
Q -->|"要加 / 改一个 provider 的异常处理"| A2
style Q fill:#cef,stroke:#369
一分钟自检¶
线上看到一个错时,先按这个顺序问 4 个问题:
1. 是哪个异常类?¶
去 01-exception-catalog.md 查表,或直接 grep:
2. 这个异常会让 Router 怎么反应?¶
- 进了 cooldown 白名单吗?→ 03-router-behavior.md §9 完整反应链速查
- 会被自动 retry 吗?→ 03-router-behavior.md §3 _should_retry 白名单
- fallback 链会不会被触发?→ 03-router-behavior.md §6 Fallback 三层链
3. 客户端看到的是什么?¶
- proxy 返回的 HTTP status_code → 04-where-to-see.md §2 客户端可见
- error.message 长啥样 → 04-where-to-see.md §2.2 message 拼装规则
4. 哪里能复现 / 看到这次的具体信息?¶
- proxy stdout(开发本地) → grep
litellm.<XxxError> - S3 raw log →
error_information.error_class字段 - PaaS 告警 → 见 04-where-to-see.md §6 PaaS 告警字段
- Prometheus →
litellm_deployment_cooled_down_total{litellm_model_name=...}
跟 Cooldown 文档的关系¶
本系列与 docs/cooldown/ 是互补关系:
| 维度 | docs/cooldown/ | docs/errors/ |
|---|---|---|
| 切入点 | "deployment 健康状态怎么管的" | "这个错是什么、谁该处理" |
| 关注 | DualCache / Redis key / V1/V2 触发路径 | 异常类继承 / status_code 映射 / Router 反应 |
| 受众 | 想理解 cooldown 机制本身 | 想从错误名倒推根因 |
| 重叠 | 第一关白名单(01 §2) | 03-router-behavior.md 复用并补充语义层解释 |
如果你想看 Redis key、TTL、DualCache 双层细节 → 去 cooldown 系列。 如果你想看"日志里这个错是啥" → 留在 errors 系列。
关于本系列文档¶
- 行号引用基于
dev-TCLOUD-11677-auto-router分支同步点(2026-05),master 可能漂移 - 跨 provider 不一致点是从实际代码扫出来的(详见 02 §4 已知不一致),不是搬运上游 docs
- 上游 LiteLLM 没有等价文档——
exceptions.py注释只标注 "OpenAI Exception Types",对映射层和 Router 联动没有系统化说明