> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tapapi.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 错误码与重试

> HTTP 状态码语义、是否重试和排障入口

Tapapi 的公开 API 以 OpenAI 兼容错误格式为主。生产代码不要只看 HTTP 状态码，还要读取 `error.code`、`error.message` 和响应头里的 `X-Oneapi-Request-Id`：状态码告诉你大类，`error.code` 才能区分余额、参数、上游异常和内容拦截，`request_id` 用于后续排障和对账。

|      HTTP     | 含义            | 处理                                                   |
| :-----------: | ------------- | ---------------------------------------------------- |
|    **200**    | 请求成功          | 文本读取 `choices`，图片读取 `data[].url` 或 `data[].b64_json` |
|    **400**    | 请求字段错误        | 不重试，按 `error.message` 修正参数                           |
|    **401**    | API Key 缺失或无效 | 检查 `Authorization: Bearer sk-xxx`                    |
|    **403**    | 账户、权限、余额或订阅不足 | 重点看 `error.code`，余额不足通常是 `insufficient_user_quota`   |
|    **413**    | 请求体过大         | 缩小图片、文件或请求体                                          |
|    **422**    | 内容或参数被上游拒绝    | 调整 prompt、图片或模型参数                                    |
|    **429**    | 限流或上游负载饱和     | 降并发，指数退避后有限重试                                        |
|   **临时 5xx**  | 平台或上游临时异常     | 只做有限重试，并记录请求信息                                       |
| **504 / 524** | 长时间无结果或网关超时   | 不要立即盲重试，先看 [超时处理](/production/timeouts)              |

错误响应格式：

```json theme={null}
{
  "error": {
    "message": "... (request id: 20260609...)",
    "type": "new_api_error",
    "code": "invalid_request"
  }
}
```

响应头也会带请求标识：

```http theme={null}
X-Oneapi-Request-Id: 20260609...
```

部分错误可能没有稳定的 `error.code`，或者 `code` 为空。生产代码应同时记录 HTTP 状态码、`error.type`、`error.code`、`error.message` 和 `request_id`，不要只依赖单个字段。

## 常见 code

| code                             | 常见含义               | 建议                   |
| -------------------------------- | ------------------ | -------------------- |
| `invalid_request`                | 参数缺失、格式错误或接口不支持该字段 | 不重试，修请求              |
| `read_request_body_failed`       | 请求体读取失败或过大         | 不重试同一请求，缩小请求体        |
| `model_not_found`                | 模型不存在或当前分组不可用      | 检查模型名和账户权限           |
| `insufficient_user_quota`        | 余额、订阅或令牌额度不足       | 充值、升级或切换账户           |
| `pre_consume_token_quota_failed` | 预扣令牌额度失败           | 不重试，检查 API Key 额度或余额 |
| `sensitive_words_detected`       | 命中敏感词或内容策略         | 修改 prompt 或输入内容      |
| `prompt_blocked`                 | 上游内容安全拦截           | 修改 prompt、图片或切换模型    |
| `bad_response_status_code`       | 上游返回异常状态           | 可按 5xx/429 策略有限重试    |
| `bad_response`                   | 上游响应格式不符合预期        | 保留响应和 request id 排障  |
| `bad_response_body`              | 上游响应体不可解析          | 通常不要重复重试，保留响应排障      |
| `empty_response`                 | 上游空响应              | 有限重试一次，仍失败则排障        |
| `api_not_implemented`            | 当前接口未实现或尚未开放       | 换已开放接口，不重试           |

<Note>余额不足不要写死判断 `402`。当前后端的余额、订阅和令牌额度不足主路径通常返回 `403`，并通过 `error.code: "insufficient_user_quota"` 表达。</Note>

## 重试建议

以下是客户业务侧的重试建议，不等同于 Tapapi 平台内部的通道重试策略。平台内部可能为了换通道做有限重试，但你的业务代码仍不应自动重试鉴权、余额、权限和参数错误。

生产代码建议按三类处理：

| 类型     | 包含                                                                      | 处理                           |
| ------ | ----------------------------------------------------------------------- | ---------------------------- |
| 不重试    | 400 / 401 / 413 / 422、余额不足、权限不足、`model_not_found`、`api_not_implemented` | 修请求、充值、换模型或联系支持              |
| 可有限重试  | 429、临时 5xx、`empty_response`、网络中断                                        | 指数退避，最多 1-2 次，并带随机抖动         |
| 先确认再重试 | 504 / 524、前端 timeout、图片 URL 下载失败、流式中断                                   | 先查业务记录、用量日志和保存状态，确认没有有效结果再补跑 |

推荐退避节奏：

```text theme={null}
第 1 次失败 -> 等 1-2 秒
第 2 次失败 -> 等 3-5 秒
第 3 次失败 -> 停止自动重试，记录并告警
```

批量任务要加随机抖动，避免所有 worker 同时重试。

## 生产日志必须记录

| 字段                             | 用途                                              |
| ------------------------------ | ----------------------------------------------- |
| `request_id`                   | 由 `X-Oneapi-Request-Id` 返回，排障第一定位字段             |
| 业务 `task_id`                   | 和你的订单、图片、用户操作关联                                 |
| 模型名                            | 排查模型权限、价格、耗时和上游状态                               |
| HTTP 状态码                       | 判断错误大类                                          |
| `error.code` / `error.message` | 判断是否重试、是否余额不足、是否内容拦截                            |
| 请求摘要                           | 保存脱敏后的 prompt、尺寸、`n`、输入图片数量                     |
| 返回摘要                           | 文本 token、图片 `data.length`、`url` / `b64_json` 类型 |

## 图片返回异常

| 现象                                | 建议                                      |
| --------------------------------- | --------------------------------------- |
| `data` 为空                         | 当作生成失败处理，记录模型、请求时间和业务 `task_id`         |
| 只有 `b64_json`                     | 解码后转存，不要只读取 `url`                       |
| 返回张数少于请求 `n`                      | 按实际返回张数处理，缺失图片单独补跑                      |
| 返回张数多于请求 `n`                      | 业务只处理需要的数量；当前公开主路径计费会封顶到请求的 `n`         |
| URL 下载失败                          | 后端服务重试下载；仍失败时保留原始返回和错误码                 |
| `error.type: "image_proxy_error"` | 可能是签名过期、上游下载失败、白名单校验失败或代理取图超时，尽快转存到自有存储 |

## 任务类错误

当前文本和普通图片请求优先按同步接口理解。视频和异步任务按受控开放能力处理，错误响应可能不是完全相同的 OpenAI 兼容格式，可能直接返回 `code`、`message`、`status_code`。业务侧仍应统一记录：

* 业务 `task_id`
* Tapapi 返回的 `request_id`
* HTTP 状态码
* `error.code`
* `error.message`
* 模型名和请求时间

<Note>限流细则放在 [限流与并发](/production/rate-limits)，超时细则放在 [超时处理](/production/timeouts)。</Note>
