الأخطاء
كل خطأ يعود بجسم JSON واحد الشكل، ورمز نصّي ثابت لا يتغيّر بتغيّر صياغة الرسالة. ابنِ منطقك على code لا على نصّ الرسالة.
صيغة الخطأ
json
{
"error": {
"code": "insufficient_credit",
"message": "الرصيد لا يكفي لتنفيذ الطلب"
}
}رموز الحالة
| الحالة | الرمز | المعنى وما تفعله |
|---|---|---|
| 401 | unauthorized | مفتاح مفقود أو غير صالح أو مُبطَل. تحقّق من الترويسة ومن أن المفتاح لم يُبطَل. |
| 402 | insufficient_credit | الرصيد لا يكفي. الطلب مسموح والصلاحية موجودة — الناقص مالٌ يُشحن. افتح صفحة الشحن للمستخدم بدل إظهار «ممنوع». |
| 404 | not_found | اسم نموذج غير معروف. راجع قائمة النماذج من GET /v1/models. |
| 422 | validation_error | طلب غير صالح: حقل ناقص أو قيمة خارج المدى (temperature، max_tokens، عدد الرسائل). |
| 429 | rate_limited | تجاوزت حدّ الطلبات في الدقيقة. نافذة الحدّ دقيقة واحدة، فانتظر حتى 60 ثانية ثم أعد المحاولة بتباعد متزايد. |
| 500 | internal_error | خطأ غير متوقع عندنا. أعد المحاولة، وإن تكرّر راسلنا بحقل id ووقت الطلب. |
سياسة إعادة المحاولة
أعد المحاولة مع 429 و5xx فقط، بتباعد أسّي وعشوائية بسيطة (مثلًا ثانية، ثم ثانيتان، ثم أربع). لا تُعد المحاولة أبدًا مع 401 و402 و404 و422: تكرارها لن يغيّر النتيجة، وسيقرّبك من حدّ المعدّل بلا فائدة.
javascript
const RETRYABLE = new Set([429, 500, 502, 503, 504])
async function callWithRetry(body, attempt = 0) {
const response = await fetch("https://<host>/v1/chat/completions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.VORIX_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
})
if (response.ok) return response.json()
const { error } = await response.json()
// Retrying never fixes an empty balance: send the user to top up.
if (response.status === 402) throw new InsufficientCredit(error.message)
if (RETRYABLE.has(response.status) && attempt < 4) {
// Exponential backoff with jitter, so every client does not retry at
// the same instant and create a second wave worse than the first.
const waitMs = 1000 * 2 ** attempt + Math.random() * 250
await new Promise((resolve) => setTimeout(resolve, waitMs))
return callWithRetry(body, attempt + 1)
}
throw new Error(`${error.code}: ${error.message}`)
}