تكرار السؤال: …
الإجابة المختصرة
حدد timeout دائمًا، وأعد استخدام client واحد (connection pooling)، وافحص status code صراحةً، وفرّق بين أخطاء النقل (timeouts وانقطاع الاتصال) وأخطاء HTTP (4xx و 5xx).
الشرح
بعض المكتبات ليس لها timeout افتراضي (مثل requests)، فقد يتعلق الطلب للأبد. إنشاء client جديد لكل طلب يلغي إعادة استخدام الاتصالات ويضيف handshake في كل مرة. نجاح الاتصال لا يعني نجاح الطلب؛ استخدم raise_for_status أو افحص الحالة. أعد المحاولة فقط على الأخطاء المؤقتة (مثل 503 و 429 مع Retry-After)، ولا تسجّل headers التوثيق. للكود غير المتزامن استخدم httpx.AsyncClient أو aiohttp.
مثال بالكود
import httpx
client = httpx.Client(base_url="https://api.example.com", timeout=httpx.Timeout(5.0, connect=2.0))
def get_order(order_id: int) -> dict:
try:
response = client.get(f"/orders/{order_id}")
response.raise_for_status()
except httpx.TimeoutException as err:
raise UpstreamTimeout() from err
except httpx.HTTPStatusError as err:
if err.response.status_code == 404:
raise OrderNotFound(order_id) from err
raise
return response.json()أخطاء شائعة
- استدعاء requests.get دون timeout في كود الإنتاج.
- إنشاء client جديد داخل كل دالة طلب.