# 错误码、限流与安全重试

分清 HTTP 错误和业务状态，在结果未知时避免盲目重试，并形成可执行的排错记录。

## 核心步骤

- 同时记录 HTTP 状态和业务状态。
- 参数、鉴权、订单和额度问题先修正原因。
- 仅对确认可重试的操作使用有上限的退避。

## 适用场景与准备

适合排查失败请求或设计生产环境的错误处理。先保留一份脱敏后的请求与响应，确认目标接口的成功业务码、当前套餐 QPS 以及操作是否会消耗额度；缺少响应时明确记录为“未收到”，不要猜测服务端执行结果。

## 先看两层状态

接口可能通过 HTTP 状态、JSON 中的业务状态，或两者共同描述失败。不同接口的业务码不能混用。例如天气接口正常业务码为 100，网页正文抽取接口的正常业务码为 200；后者并不是“只检查 HTTP 200”即可。

以 [天气](https://www.gugudata.com/api/details/weatherinfo)、[PageSpeed](https://www.gugudata.com/api/details/pagespeed-score) 和 [正文抽取](https://www.gugudata.com/api/details/readability) 的详情错误表为准。代理返回的 HTML 错误页也可能不是 JSON，解析前应检查 Content-Type 和响应格式。

## 按原因决定下一步

| 现象 | 先检查什么 | 是否立即重试 |
| --- | --- | --- |
| 参数不合法 | 请求方式、编码、必填参数和取值范围 | 否，修正请求 |
| 凭据或权限失败 | AppKey 对应产品、订单状态 | 否，修正凭据或权限 |
| 额度不足 | 可用额度及消费记录 | 否，确认额度 |
| 频率受限 | 当前并发、调用频率和 QPS 权益 | 先降低负载，按响应提示等待 |
| 网络中断或超时 | 是否收到响应、服务状态 | 先判断操作能否安全重放 |
| 临时服务异常 | 接口状态及重复出现范围 | 可重试操作才有限重试 |

## 重试必须有边界

对于确认可以重放的只读请求，可以将首次请求后的重试限制为最多 2 次，并采用指数退避加随机抖动。若响应提供有效的 `Retry-After`，优先遵循该等待时间，同时受整个任务的超时预算约束。

下面只展示等待时间计算，不包含自动发起请求；由调用方依据具体接口判断是否重试。

```python
import random

def retry_delay(attempt, base=1.0, maximum=8.0):
    return min(maximum, base * (2 ** attempt) + random.uniform(0, 0.5))
```

::: warning
GET 也可能计费。POST 可能创建任务或产生其他副作用。超时不等于没有执行；支付、创建任务、写入、消耗型操作不得套用通用自动重试。有结果查询机制时先查询；无法确认执行结果时联系支持，不盲目重发。
:::

## 限流与应用排队

在应用端为同一产品建立有界队列，限制同时进行的请求数，避免所有失败请求在同一时刻重发。QPS 权益不等同于“可以无限并发”，单次调用耗时也会影响并发连接数量。按目标产品的实际 QPS 配置队列，不套用其他产品的默认值。容量评估与扩展流程见 [QPS 与升级](https://www.gugudata.com/developers/qps-and-upgrades)。

## 故障排查记录

记录发生时间与时区、接口标识、脱敏请求、HTTP 状态、业务状态和耗时；有请求追踪标识时一并保留。先用最小请求重现，再查看 [接口状态](https://www.gugudata.com/status)。向 [技术支持](https://www.gugudata.com/contact) 反馈时不要附上凭据、完整 Cookie 或未经脱敏的用户数据。

需要使用开发者中心定位异常时，可按 [请求分析与日志](https://www.gugudata.com/developers/portal/monitoring) 对照同一时段的趋势和请求明细。
