Lỗi API
Cách xử lý các lỗi từ FourA API.
Error Response Format
API trả về các đối tượng JSON phẳng cho tất cả các lỗi. Không có đối tượng error lồng nhau hoặc mã lỗi.
{
"error": "Invalid API key"
}
Một số lỗi bao gồm các trường bổ sung như status, service, retryAfter, current, hoặc limits ở cấp cao nhất:
{
"error": "Rate limit exceeded",
"status": 429,
"service": "single",
"retryAfter": 5,
"current": { "concurrency": 12, "rpm": 3000 },
"limits": { "maxConcurrency": 500, "maxRpm": 3000 }
}
Tracking a Request
Mỗi response từ API (thành công hoặc lỗi) đều bao gồm một header X-Foura-Request-Id chứa UUID cho cuộc gọi đó. Hãy ghi log giá trị này ở phía bạn. Nếu bạn cần yêu cầu hỗ trợ về một request cụ thể, ID đó sẽ giúp chúng tôi tìm thấy nó.
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
# ...
Error Types
400: Bad Request
Body của request bị thiếu các trường bắt buộc, chứa các giá trị không hợp lệ, hoặc chỉ định một mục tiêu mà API từ chối truy xuất.
{
"error": "Invalid request body format"
}
Lỗi 400 tương tự cũng áp dụng cho cơ chế bảo vệ SSRF. Nếu url của bạn phân giải thành một dải IP riêng tư, loopback, hoặc dải IP được bảo lưu khác (RFC 5735, RFC 6598, các khối IPv6 được bảo lưu), request sẽ bị từ chối trước khi rời khỏi mạng của FourA:
{
"error": "Target <ip> resolves to a private/reserved IP"
}
Cách khắc phục: Kiểm tra xem request của bạn đã bao gồm tất cả các trường bắt buộc chưa, các URL có sử dụng http:// hoặc https:// không, và host có phân giải thành một địa chỉ công khai hay không.
401: Unauthorized
API key của bạn bị thiếu hoặc không hợp lệ.
Thiếu key:
{
"error": "Missing API key. Include X-API-Key header."
}
Key không hợp lệ:
{
"error": "Invalid API key"
}
Cách khắc phục: Xác minh xem header X-API-Key của bạn có chứa một key hợp lệ hay không. Tạo một key mới từ Dashboard nếu cần.
429: Rate Limited
Bạn đã gửi quá nhiều request trong một khoảng thời gian ngắn.
{
"error": "Rate limit exceeded",
"status": 429,
"service": "single",
"retryAfter": 5,
"current": { "concurrency": 12, "rpm": 3000 },
"limits": { "maxConcurrency": 500, "maxRpm": 3000 }
}
Cách khắc phục: Chờ số giây được chỉ định trong retryAfter trước khi gửi thêm request. Xem Rate Limits để biết thêm chi tiết.
500: Server Error
Đã xảy ra lỗi từ phía chúng tôi.
Cách khắc phục: Thử lại request sau một khoảng thời gian ngắn. Nếu lỗi vẫn tiếp diễn, hãy kiểm tra status page hoặc liên hệ với bộ phận hỗ trợ kèm theo X-Foura-Request-Id từ phản hồi bị lỗi.
503: Service Disabled or At Capacity
Mã lỗi 503 có nghĩa là dịch vụ tạm thời không khả dụng để bảo trì hoặc bạn đã đạt đến giới hạn concurrency. Cả hai phản hồi đều bao gồm trường retryAfter. Định dạng lỗi concurrency cũng bao gồm current và limits.
{
"error": "Service disabled",
"status": 503,
"retryAfter": 60
}
Cách khắc phục: Chờ retryAfter giây, sau đó thử lại. Trang trạng thái liệt kê các khoảng thời gian bảo trì đang hoạt động.
Target-Side Failures Inside 200 OK
Không phải mọi lỗi đều hiển thị dưới dạng mã trạng thái HTTP khác 2xx. Khi trang web mục tiêu trả về HTTP 200 kèm theo nội dung lỗi, FourA vẫn chuyển body cho bạn nhưng phân loại request là application_error. Khi mục tiêu trả về mã khác 2xx mà các quy tắc validate của bạn không chấp nhận, kết quả sẽ là application_fail và body được truyền qua mà không thay đổi.
Cả hai trường hợp đều được tính phí như thể request đã hoạt động thành công ở cấp độ đường truyền. Tài liệu tham khảo Outcomes trình bày chi tiết toàn bộ cách phân loại này.
Response Encoding
FourA tự động giải mã các response body sang UTF-8. Nếu mục tiêu cung cấp windows-1251, gbk, shift_jis, iso-8859-*, hoặc bất kỳ charset nào khác được khai báo trong header Content-Type hoặc thẻ HTML <meta charset>, bạn sẽ nhận được một chuỗi UTF-8 sạch trong trường data (single, proxy) hoặc body (browser).
Đối với các payload nhị phân (hình ảnh, protobuf, âm thanh thô), hãy đặt returnBuffer: true trên request. Body trả về sẽ là một buffer base64 và không áp dụng chuyển đổi charset.
Retry Strategy
Một chính sách thử lại thực tế:
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:
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")
Related
- Rate Limits: Chi tiết về Concurrency và RPM
- Request Outcomes: Giải thích về bảy giá trị kết quả
- Common Issues: Triệu chứng, nguyên nhân, cách khắc phục