跳转至

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/&lt;provider&gt;/"
        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.&lt;XxxError&gt;<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

几点关键事实

  1. 异常分两层litellm/exceptions.py类型层(25 个类,每个有固定语义),litellm_core_utils/exception_mapping_utils.py映射层(按 provider × status_code 决定抛哪个类)。运维看到的所有错误名都来自类型层;要改"507 该当 5xx 处理"这种事改映射层。
  2. Router 决策只看类型层_should_retrystatus_code,cooldown 白名单看 status_code + message 字符串。所以映射层抛错才是决定 Router 行为的唯一入口——映射写错(如把 502 映射到 APIConnectionError)会直接绕过 cooldown。
  3. ProxyException 重写 status_code:Proxy 层有几条特殊规则覆盖类型层的 status_code,如 No healthy deployment available 一律转 429(_types.py:3221-3225)、tag routing 失败转 401。客户端看到的 status 不一定等于 LiteLLM 内部异常的 status。
  4. 客户端只看到 OpenAI 兼容 JSON:所有 LiteLLM 异常都继承自 openai.XxxError,最终序列化成 {error: {message, type, code, param}} 给客户端。LiteLLM-specific 字段(llm_providerlitellm_debug_infonum_retries)拼在 message 里。
  5. 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:

grep -rn "class \(\w\+Error\|Timeout\)" litellm/exceptions.py

2. 这个异常会让 Router 怎么反应?

3. 客户端看到的是什么?

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 联动没有系统化说明