Обработка rate limits
Как безопасно обрабатывать 429, throttling и лимит повторов в GonkaGate.
Сначала прочитайте error.code, а потом решайте, нужен ли retry для 429.
В GonkaGate insufficient_quota означает, что для этого запроса не хватает prepaid USD balance. rate_limit_exceeded и transfer_agent_capacity_reached обычно временные. Держите эту развилку в одном общем обработчике ретраев, чтобы все вызовы вели себя одинаково.
Решите, нужен ли retry
| Если пришло | Что это обычно значит | Что делать |
|---|---|---|
429 + insufficient_quota | Для этого запроса не хватает prepaid USD balance | Не ретрайте. Покажите состояние баланса или пополнения и повторяйте запрос только после появления средств. |
429 + rate_limit_exceeded | Трафик упёрся в лимит запросов | Учитывайте Retry-After, если он пришёл, и ретрайте с небольшим лимитом повторов. |
429 + transfer_agent_capacity_reached | Временное давление по capacity | Подождите, аккуратно повторите запрос и держите число повторов маленьким. |
429 без известного кода | Обычно это всё ещё временный throttling или pressure по capacity | Сначала трактуйте это как временный throttling, но логируйте полный ответ, если сбой повторяется. |
Используйте один общий обработчик ретраев
const sleep = (ms: number) =>
new Promise((resolve) => setTimeout(resolve, ms));
export async function requestWithRateLimitHandling(
makeRequest: () => Promise<Response>,
maxRetries = 3,
): Promise<Response> {
for (let attempt = 0; attempt <= maxRetries; attempt += 1) {
const response = await makeRequest();
if (response.status !== 429) {
return response;
}
const body = await response.clone().json().catch(() => null);
const errorCode = body?.error?.code;
if (errorCode === "insufficient_quota") {
throw new Error("insufficient_quota");
}
if (attempt === maxRetries) {
throw new Error("retry_budget_exhausted");
}
const retryAfterSeconds = Number(
response.headers.get("Retry-After") ?? "0",
);
const waitMs =
retryAfterSeconds > 0
? retryAfterSeconds * 1000
: Math.min(1000 * 2 ** attempt, 8000);
await sleep(waitMs);
}
throw new Error("retry_budget_exhausted");
}Эта базовая политика делает четыре вещи: ветвится по error.code, останавливается на insufficient_quota, учитывает Retry-After и ограничивает число повторов.
Сначала читайте эти поля
- HTTP status
429 error.codeв JSON bodyRetry-After, если сервер точно говорит, сколько ждатьx-ratelimit-*, если клиент их видит, чтобы логировать текущий лимит, оставшийся запас и окно сбросаx-request-idдля повторяющихся сбоев или эскалации в саппорт
Поле error.message используйте только как человекочитаемый контекст. Не стройте retry-логику по тексту сообщения.
Частые ошибки
- Считать любой
429обычным throttling. В GonkaGateinsufficient_quota— это состояние биллинга, а не повод для backoff. - Игнорировать
Retry-After, если он пришёл. Обычно это приводит к синхронным retry и новому throttling. - Прятать
insufficient_quotaза автоматическими ретраями. Остановитесь и покажите состояние биллинга или пополнения. - Давать воркерам, cron-job’ам или batch-трафику ретраить бесконечно. Держите лимит повторов маленьким и защищайте пользовательский трафик.
Смотрите также
- Обработку ошибок API в GonkaGate, если нужна та же логика retry-or-stop для
401,403,5xxи других non-429ошибок. - Pricing для правил prepaid USD balance за
insufficient_quota. - Создать chat completion для точного контракта
POST /v1/chat/completions.
Была ли эта страница полезной?