Грешки в API
Как да обработвате грешки от FourA API.
Формат на отговора при грешка
API връща плоски JSON обекти за всички грешки. Няма вложен обект error или кодове за грешки.
{
"error": "Invalid API key"
}
Някои грешки включват допълнителни полета като status, service, retryAfter, current или limits на най-високо ниво:
{
"error": "Rate limit exceeded",
"status": 429,
"service": "single",
"retryAfter": 5,
"current": { "concurrency": 12, "rpm": 3000 },
"limits": { "maxConcurrency": 500, "maxRpm": 3000 }
}
Проследяване на request
Всеки API response (успешен или грешка) включва X-FourA-Request-Id header с UUID за това извикване. Логнете го при вас. Ако трябва да попитате съпорта какво се е случило с конкретен request, това ID ни позволява да го намерим.
curl -i -X POST https://eu.api.foura.ai/api/single/ \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"method": "GET", "url": "https://example.com"}'
# HTTP/1.1 200 OK
# X-FourA-Request-Id: 9f1c4e6c-7b2a-4d3e-8a1f-2c9d8e4a3b15
# Content-Type: application/json
# ...
Типове грешки
400: Bad Request
Тялото на заявката не съдържа задължителни полета, съдържа невалидни стойности или посочва цел, която API отказва да извлече.
{
"error": "Invalid request body format"
}
Същият 400 покрива и защитата от SSRF. Ако вашият url се разрешава до частен, loopback или друг резервиран IP обхват (RFC 5735, RFC 6598, IPv6 резервирани блокове), заявката се отхвърля, преди да напусне мрежата на FourA:
{
"error": "Target <ip> resolves to a private/reserved IP"
}
Невалиден JSON в тялото се отхвърля по същия начин, преди да бъде прочетено което и да е поле:
{
"error": "Invalid JSON in request body"
}
Полетата proxy и ignoreProxies имат свои собствени 400 грешки. И двете приемат непрозрачни proxy идентификатори, които са били върнати от предишни response, така че всичко друго не успява да се декодира:
| Съобщение | Какво се случи |
|---|---|
Invalid proxy format |
Стойността proxy не е proxy ID, издадено от FourA. Тук попадат необработени proxy адреси. |
Invalid ignoreProxies format |
Един от записите в ignoreProxies не е proxy ID. |
Proxy not found |
Идентификаторът е декодиран успешно, но вече не води към активен изход. Изберете нов. |
Решение: Проверете дали вашият request включва всички задължителни полета, дали URL адресите използват http:// или https://, дали хостът се разрешава до публичен адрес и дали всяка стойност на proxy е идентификатор, копиран буквално от предишен response.
401: Неоторизиран
Вашият API ключ липсва или е невалиден.
Липсващ ключ:
{
"error": "Missing API key. Include X-API-Key header."
}
Невалиден ключ:
{
"error": "Invalid API key"
}
Решение: Уверете се, че вашият X-API-Key header съдържа валиден ключ. Генерирайте нов ключ от Dashboard, ако е необходимо.
429: Rate Limited
Изпратили сте твърде много заявки за кратък период от време.
{
"error": "Rate limit exceeded",
"status": 429,
"service": "single",
"retryAfter": 5,
"current": { "concurrency": 12, "rpm": 3000 },
"limits": { "maxConcurrency": 500, "maxRpm": 3000 }
}
Решение: Изчакайте броя секунди в retryAfter преди да изпратите още requests. Вижте Rate Limits за подробности.
500: Сървърна грешка
Нещо се обърка от наша страна.
Решение: Опитайте отново вашия request след кратко забавяне. Ако грешката продължава, проверете страницата за състоянието или се свържете с поддръжката, като предоставите X-FourA-Request-Id от неуспешния response.
502: Upstream недостъпен
FourA достигна своя собствен engine, но не можа да използва отговора.
{
"error": "Upstream unavailable",
"details": "..."
}
Решение: Опитайте отново с кратко забавяне. Това е проблем от наша страна, затова не ви струва нищо: резултатът е service_error и само success се таксува.
504: Upstream Timeout
Енджинът не приключи в рамките на времевия бюджет за тази заявка.
{
"error": "Upstream timeout",
"details": "the backend did not finish inside the time budget for this request"
}
Грешка 504 е свързана с това колко време е отнела работата, а не с вашия ключ, вашите параметри или вашия proxy. Бавните цели, студените решения на предизвикателства и големите страници са обичайните причини.
Решение: Увеличете timeout_ms в заявката (Single приема до 120000, Browser до 120000, Auto до 180000) или опитайте отново. FourA изчаква декларирания от вас бюджет плюс малък марж, така че искането на повече време наистина осигурява повече време.
503: Услугата е деактивирана или е достигнат капацитетът
Грешка 503 означава, че услугата е временно недостъпна за поддръжка или сте достигнали лимита за паралелност. И двата отговора включват поле retryAfter. Формата за паралелност също включва current и limits.
{
"error": "Service disabled",
"status": 503,
"retryAfter": 60
}
Решение: Изчакайте retryAfter секунди, след което опитайте отново. Страницата за състоянието показва активните прозорци за поддръжка.
Трети вариант на 503 няма retryAfter. Това означава, че системата зад вашия endpoint се е рестартирала, когато заявката ви е пристигнала:
{
"error": "Backend service unavailable",
"backend_status": 503
}
Опитайте отново след секунда или две.
Четене на грешки от /api/auto/
POST /api/auto/ отговаря с HTTP 200 винаги, когато стълбата е изпълнена, дори когато всяко стъпало е неуспешно. Действителният резултат се намира в body:
{
"status": 0,
"error": "all attempts failed",
"attempts": 7,
"meta": { "rung": "fail", "solved": false, "attempts": 7, "credits": 47 }
}
Затова не разклонявайте логиката въз основа на транспортния статус за Auto. Вместо това четете status и error от body. Истински non-200 статус от /api/auto/ означава, че FourA е отхвърлил заявката преди стартирането на стълбицата: 401, 400, 429 или 503, всички документирани по-горе.
Грешки от страна на целта вътре в 200 OK
Не всяка грешка се появява като non-2xx HTTP статус. Когато целевият сайт върне HTTP 200 с payload за грешка, FourA все пак ви предава body, но класифицира заявката като application_error. Когато целта върне non-2xx, който вашите validate правила не приемат, резултатът е application_fail и body преминава непроменено.
И двата случая се таксуват, сякаш заявката е работила на мрежово ниво. Справката за Изходи покрива пълната таксономия.
Кодиране на response
FourA автоматично декодира response телата до UTF-8. Ако целта обслужва windows-1251, gbk, shift_jis, iso-8859-* или какъвто и да е друг charset, деклариран в Content-Type header или HTML <meta charset> таг, вие получавате чист UTF-8 низ в полето data (single, proxy) или body (browser).
За двоични payloads (изображения, protobuf, сурово аудио), задайте returnBuffer: true на заявката. Body се връща като base64 буфер без приложено транскодиране на charset.
Стратегия за повторен опит
Практична политика за повторен опит:
import time
import requests
def make_request(url, payload, api_key, max_retries=3):
for attempt in range(max_retries):
resp = requests.post(
url,
headers={"X-API-Key": api_key, "Content-Type": "application/json"},
json=payload,
)
if resp.status_code == 200:
return resp.json()
body = resp.json() if resp.headers.get("content-type", "").startswith("application/json") else {}
retry_after = body.get("retryAfter", 2 ** attempt)
request_id = resp.headers.get("X-FourA-Request-Id", "?")
if resp.status_code in (429, 503):
time.sleep(retry_after)
continue
if resp.status_code >= 500: # 500, 502, 503, 504 are all ours to fix
time.sleep(2 ** attempt)
continue
# 400/401/404 won't fix themselves
raise RuntimeError(f"{resp.status_code} (request {request_id}): {body.get('error')}")
raise RuntimeError(f"Exhausted {max_retries} retries")
Свързани
- Rate Limits: Подробности за паралелност и RPM
- Резултати от заявките: Обяснение на седемте стойности на резултатите
- Често срещани проблеми: Симптоми, причини, решения
- Anti-Bot защити: Когато body е страница с предизвикателство, а не грешка