# 错误处理

## 统一错误响应格式

所有 API 错误返回统一的 JSON 格式：

```json
{
  "code": 2010,
  "message": "Insufficient credits",
  "suggestion": "Please top up your account at https://platform.tripo3d.ai",
  "request_id": "req_abc123"
}
```

| 字段 | 类型 | 说明 |
| :-: | :-: | :-: |
| code | integer | 错误码 |
| message | string | 错误描述 |
| suggestion | string | 修复建议 |
| request_id | string | 请求唯一标识，用于排查问题 |

## HTTP 状态码

| 状态码 | 含义 | 说明 |
| :-: | :-: | :-: |
| 200 | 成功 | 请求处理成功 |
| 400 | 参数错误 | 请求参数缺失或格式不合法 |
| 401 | 未认证 | API Key 缺失或无效 |
| 403 | 权限不足 | 无权访问该资源或积分不足 |
| 404 | 资源不存在 | 请求的任务或资源不存在 |
| 429 | 请求过多 | 触发速率限制，请降低请求频率 |
| 500 | 服务错误 | 服务端内部错误，请稍后重试 |

## 错误码表

| 错误码 | 含义 | 建议处理方式 |
| :-: | :-: | :-: |
| 1000 | API Key 无效 | 检查 API Key 是否正确，是否已被删除 |
| 1001 | 未授权 | 检查请求头中是否携带了 Authorization |
| 2000 | 超过速率限制 | 降低请求频率，实施指数退避重试 |
| 2002 | 不支持的请求参数 | 检查请求体字段名和值是否符合文档要求 |
| 2003 | 输入文件为空 | 确认上传的文件不为空且格式正确 |
| 2004 | 不支持的文件类型 | 检查文件格式是否在支持列表内 |
| 2008 | 内容政策违规 | 修改输入内容，避免违规词汇或图片 |
| 2010 | 积分不足 | 前往控制台充值积分 |
| 2015 | 版本已弃用 | 升级到最新 API 版本 |
| 2018 | 模型太复杂 | 降低输入模型的复杂度或面数 |

## 错误处理示例

### Python

```python
import time
import requests

def call_api_with_retry(url, headers, payload=None, max_retries=3):
    for attempt in range(max_retries):
        if payload:
            response = requests.post(url, headers=headers, json=payload)
        else:
            response = requests.get(url, headers=headers)

        if response.status_code == 200:
            return response.json()

        if response.status_code == 429:
            wait = 2 ** attempt
            print(f"触发限流，{wait} 秒后重试...")
            time.sleep(wait)
            continue

        error = response.json()
        raise Exception(
            f"API 错误 [{error['code']}]: {error['message']} "
            f"(建议: {error.get('suggestion', '无')})"
        )

    raise Exception("重试次数已用尽")
```

### JavaScript

```javascript
async function callApiWithRetry(url, options, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url, options);

    if (response.ok) {
      return await response.json();
    }

    if (response.status === 429) {
      const wait = 2 ** attempt * 1000;
      console.log(`触发限流，${wait / 1000} 秒后重试...`);
      await new Promise(resolve => setTimeout(resolve, wait));
      continue;
    }

    const error = await response.json();
    throw new Error(
      `API 错误 [${error.code}]: ${error.message} (建议: ${error.suggestion || "无"})`
    );
  }

  throw new Error("重试次数已用尽");
}
```

## 重试策略建议

对于可重试的错误（429 限流、500 服务错误），建议使用指数退避策略：

1. 第 1 次重试：等待 1 秒
2. 第 2 次重试：等待 2 秒
3. 第 3 次重试：等待 4 秒
4. 最大重试次数不超过 5 次

对于不可重试的错误（400、401、403），应直接抛出异常并修复问题。
