# 错误码与限流
> 每个状态码意味着什么、该不该重试、怎么重试
> 错误结构分同步与异步两种
> 排查顺序见[常见问题](faq.html)
## 错误格式
同步接口失败时返回统一结构：
```json
{
  "error": {
    "code": 401,
    "message": "身份验证失败，请检查您的API密钥",
    "type": "authentication_error"
  }
}
```
| 字段 | 类型 | 说明 |
|---|---|---|
| `error` | object | 错误容器，所有失败响应都包在这一层里 |
| `error.code` | integer | HTTP 状态码，与响应状态行一致 |
| `error.message` | string | 错误描述，面向开发者阅读 |
| `error.type` | string | 错误类型，机器可读，用于程序分支判断 |
程序按 `type` 分支即可，不必解析 `message`。
> **Note:** 
> 不要用 `message` 做字符串匹配来判断错误原因。文案可能随版本调整，只有 `type` 与 `code` 是稳定的契约。
### 异步任务的错误
异步任务（图像、视频）失败时，查询任务这一步本身是成功的，HTTP 状态是 200，失败信息在任务对象的 `status` 与 `error` 里：
```json
{
  "code": 200,
  "data": {
    "id": "task_01KA",
    "status": "failed",
    "error": {
      "code": "content_policy_violation",
      "message": "提示词触发内容审核",
      "type": "invalid_request_error"
    }
  }
}
```
注意这里的 `error.code` 是字符串，同步接口的 `error.code` 是数字，解析时要按两种类型分别处理。完整字段见[任务响应](../api/tasks/response.html)。
### 流式响应中的错误
流式响应开始后发生的错误以 SSE 事件发送，HTTP 状态仍是 200。客户端必须处理流内的错误事件，否则会表现为「输出突然中断」。
## 状态码速查
| 状态 | type | 含义 | 可否重试 |
|---|---|---|---|
| 400 | `invalid_request_error` | 参数格式错误，或当前模型不支持该字段 | 否，先修正请求 |
| 401 | `authentication_error` | Key 缺失、无效或已停用 | 否 |
| 402 | `payment_required` | 余额不足 | 否，充值后再试 |
| 403 | `permission_error` | 无访问权限，或分组不允许调用该模型 | 否 |
| 404 | `not_found_error` | 路径或资源不存在，常见于地址多写或少写 `/v1` | 否 |
| 409 | `conflict` | 资源状态冲突，如任务尚未完成 | 稍后 |
| 429 | `rate_limit_error` | 触发限流 | 是，退避后重试 |
| 500 | `server_error` | 服务端异常 | 是 |
| 502 | `bad_gateway` | 上游不可用 | 是 |
| 503 | `service_unavailable` | 服务暂时不可用 | 是 |
## 429 的处理
429 是最需要区分对待的一种。响应头里带 `Retry-After` 时按它等待，没有时按指数退避，从 1–2 秒起步。
触发限流通常有三类原因：
- **账户并发过高**：同时在跑的请求太多，降低并发或串行化
- **单位时间请求数超限**：把请求摊开到更长时间里
- **上游容量饱和**：同一分组内的上游账号暂时都在限流，稍等会自动恢复
控制台「用量」页面能看到近期的请求量与失败分布，先确认是哪一类，再决定是降并发还是等一等。
## 重试建议
**可以重试**：429、500、502、503。
**不要原样重试**：400、401、402、403、404、409。这些是请求本身或账户状态的问题，重试不会变好，先按上表修正。
**流式请求**：收到流内错误事件后，如果此前没有拿到任何内容，可以按 5xx 处理重试一次；已经收到部分内容时不要盲目重试，会产生重复计费。
按 `type` 分流的写法：
```python
RETRYABLE = {"rate_limit_error", "server_error", "bad_gateway", "service_unavailable"}
def handle_error(body):
    err = body["error"]
    if err["type"] in RETRYABLE:
        return "retry"
    if err["type"] == "authentication_error":
        raise SystemExit("检查 API Key")
    if err["type"] == "payment_required":
        raise SystemExit("余额不足，请充值")
    return "fail"
```
网关内部已经在同一分组的多个上游之间做过故障转移，客户端不必把重试间隔设得太短——频繁重试反而容易被判定为异常流量。
## 并发与速率
不同分组、不同模型的上限不一样，具体数值以控制台显示的为准。工程上建议：
- 服务端集成用连接池复用连接，避免每次请求新建
- 批量任务用队列限速，不要一次性打满
- 遇到 429 时先降速，再逐步回升，不要立刻恢复原并发
## 还没解决
写邮件到 [support@oairoute.com](mailto:support@oairoute.com)，附上：
1. 请求时间与接口路径
2. HTTP 状态码与完整错误体
3. `Retry-After` 等响应头
4. Key 名称（不要贴完整 Key）
