تستخدم كلتا واجهتي ResQ رموز حالة HTTP القياسية، وتُرجِع غلاف JSON صغيرًا
عند الفشل. تعامَل مع رمز الحالة على أنه المرجع؛ وتعامَل مع الجسم على أنه
تفاصيل تشخيصية للسجلات وواجهات المشغّل — وليس للتحكم بالتدفق.
الغلاف
تُرجِع Infrastructure API:
{ "error": "Invalid credentials" }
تُرجِع Coordination API نفس الشكل، أو غلافًا أكثر ثراءً على نقاط النهاية
التي تُبلِّغ عن إخفاقات متعددة:
{
"error": "validation_failed",
"message": "field 'mission_id' is required",
"details": [
{ "path": "mission_id", "rule": "required" }
]
}
دائمًا تشعَّب بناءً على رمز حالة HTTP. قد تتطور أسماء الحقول داخل الجسم؛
أما رموز الحالة فهي مستقرة.
رموز الحالة
| الرمز | الاسم | المعنى |
|---|
200 | OK | نجاح. |
201 | Created | تم إنشاء مورد جديد (مثل رفع دليل). |
202 | Accepted | تم وضع الطلب في الطابور — عادةً قياس عن بُعد أو عمل غير متزامن. |
204 | No Content | نجاح بدون جسم. |
400 | Bad Request | JSON مشوّه أو معاملات غير صالحة. |
401 | Unauthorized | التوكن مفقود أو منتهي أو غير صالح. |
403 | Forbidden | التوكن يفتقر إلى نطاق الصلاحية المطلوب للمورد. |
404 | Not Found | المورد غير موجود أو غير مرئي للمشغّل. |
409 | Conflict | حالة المورد تمنع العملية (مثل مهمة تمت الموافقة عليها مسبقًا). |
422 | Unprocessable Entity | فشل التحقق على طلب جيد التكوين. |
429 | Too Many Requests | تجاوز حد المعدل. التزم بـ Retry-After. |
500 | Internal Server Error | عطل خادم غير متوقع. آمن لإعادة المحاولة. |
503 | Service Unavailable | تبعية أمامية متدهورة. آمن لإعادة المحاولة مع تراجع. |
ما الذي ينبغي إعادة محاولته
| الفئة | إعادة المحاولة؟ | الاستراتيجية |
|---|
4xx (باستثناء 408، 409، 429) | لا | أصلِح الطلب. |
408 Request Timeout | نعم | محاولة واحدة. |
409 Conflict | أحيانًا | أعد قراءة الحالة، ثم قرّر. |
429 Too Many Requests | نعم | التزم بـ Retry-After، ثم تراجع أُسّي مع jitter. |
5xx | نعم | تراجع أُسّي مع jitter، بحدّ ~30 ثانية. |
مخطّط للتراجع
async function withRetry<T>(fn: () => Promise<T>, max = 4): Promise<T> {
let attempt = 0;
while (true) {
try {
return await fn();
} catch (err: any) {
const status = err?.status ?? 0;
const retryable = status === 429 || status >= 500;
if (!retryable || attempt >= max) throw err;
const base = 250 * 2 ** attempt;
const jitter = Math.random() * base;
await new Promise((r) => setTimeout(r, base + jitter));
attempt++;
}
}
}
أخطاء شائعة
401 Unauthorized
{ "error": "Token expired" }
أعد تشغيل تدفق تسجيل الدخول الموصوف في
المصادقة ثم أعد المحاولة مرة واحدة.
403 Forbidden
{ "error": "Insufficient scope: missions.approve" }
المشغّل مُصادَق لكنه لا يمتلك نطاق الصلاحية المطلوب. اعرض هذا للمستخدم؛
ولا تُعد المحاولة. تتطلب تدفقات الموافقة على المهام تحديدًا مشغّلين
مُخوَّلين عبر HITL (المادة 14 من قانون الذكاء الاصطناعي الأوروبي).
429 Too Many Requests
تتضمن الاستجابة رأس Retry-After بالثواني التي ينبغي الانتظار قبل
إعادة المحاولة. توقّف لما لا يقل عن تلك المدة قبل المحاولة من جديد.
503 Service Unavailable
الشبكة المتراصة أو إحدى التبعيات الأمامية متدهورة. تم تصميم Coordination
API للاستمرار في العمل في هذه الحالة — يحفظ استيعاب القياس عن بُعد
محليًا على الحافة ويُعيد المحاولة. ينبغي لطلبات العميل ذات
الـ idempotency أن تُعيد المحاولة مع تراجع.
الإبلاغ عن خطأ
إذا واجهت إخفاقًا قابلاً للتكرار لا يطابق هذا المرجع، افتح issue على
مستودع الوثائق
مع:
- طريقة HTTP، والمسار، ورمز الحالة
- Request ID (رأس الاستجابة
X-Request-Id) إن وُجد
- نسخة منقَّحة من جسم الطلب
- الجسم الكامل للاستجابة