معالجة الأخطاء

كل خطأ من كلمات له رمز قابل للقراءة آلياً، ورسالة قابلة للقراءة البشرية، ورمز حالة HTTP.

تنسيق استجابة الخطأ

عند الخطأ، حقل data يكون null وحقل error يحتوي على كائن منظّم:

error-response.json
{  "data": null,  "error": {    "code": "ERR_VALIDATION",    "message": "Parameter 'letters' must be an integer between 1 and 20.",    "field": "letters"  },  "meta": {    "requestId": "req_01j9abc...",    "responseTimeMs": 2  }}
الحقلالنوعالوصف
error.codestringمعرّف الخطأ القابل للقراءة آلياً. استخدمه للتعامل البرمجي مع الأخطاء.
error.messagestringوصف قابل للقراءة البشرية. آمن للعرض للمطوّرين، ليس للمستخدمين النهائيين.
error.fieldstring?موجود في ERR_VALIDATION — اسم المعامل غير الصالح.
error.limitnumber?موجود في ERR_RATE_LIMIT_EXCEEDED — حدك اليومي.
error.resetAtstring?موجود في ERR_RATE_LIMIT_EXCEEDED — طابع زمني ISO 8601 لوقت إعادة ضبط الحد.

جميع رموز الأخطاء

الرمزHTTPDescriptionالإجراء
ERR_AUTH_MISSING401لم يُقدَّم مفتاح API.أضف ترويسة Authorization: Bearer ... أو x-api-key.
ERR_AUTH_INVALID401مفتاح API غير موجود.المفتاح لا يطابق أي مفتاح نشط. تحقق من الأخطاء الإملائية.
ERR_AUTH_REVOKED401مفتاح API مُلغى.أنشئ مفتاحاً جديداً من لوحة التحكم.
ERR_RATE_LIMIT_EXCEEDED429تجاوز حد الطلبات اليومي.تحقق من ترويسة X-RateLimit-Reset لمعرفة وقت إعادة ضبط الحد.
ERR_VALIDATION400معاملات طلب غير صالحة.رسالة الخطأ تحدد الحقل غير الصالح.
ERR_NOT_FOUND404المورد غير موجود.الكلمة أو الجذر أو معرّف المورد المطلوب غير موجود.
ERR_PLAN_LIMIT403الميزة غير متاحة في الخطة الحالية.رقّ للوصول إلى هذه النقطة أو المعامل.
ERR_INTERNAL500خطأ داخلي في الخادم.حدث خطأ غير متوقع. أعد المحاولة بالتراجع الأسي.

معالجة الأخطاء في SDK

يُصدّر SDK فئات أخطاء مُنمَّطة لكل رمز خطأ. استخدم فحوصات instanceof للتعامل الدقيق:

error-handling.ts
import {  KalimaLab,  RateLimitError,  AuthError,  NotFoundError,  ValidationError,  KalimaLabError,} from '@kalimalab/sdk'const client = new KalimaLab({ apiKey: process.env.KALIMALAB_API_KEY! })async function getWord(id: string) {  try {    return await client.words.get(id)  } catch (err) {    if (err instanceof RateLimitError) {      // Specific: rate limit info available      console.error(`Rate limit hit. Limit: ${err.limit}, resets at: ${err.resetAt}`)      return null    }    if (err instanceof AuthError) {      // Auth problem — check key      console.error(`Auth error [${err.code}]: ${err.message}`)      throw err    }    if (err instanceof NotFoundError) {      // Word doesn't exist      return null    }    if (err instanceof ValidationError) {      // Bad parameters      console.error(`Validation error on field: ${err.field}`)      throw err    }    if (err instanceof KalimaLabError) {      // Any other KalimaLab API error      console.error(`API error ${err.status}: ${err.code}`)    }    throw err  }}

معالجة الأخطاء مع fetch الأصلي

typescript
async function fetchWord(id: string) {  const res = await fetch(`https://api.kalimalab.com/v1/words/${id}`, {    headers: { Authorization: `Bearer ${process.env.KALIMALAB_API_KEY}` },  })  const body = await res.json()  if (!res.ok) {    const { code, message } = body.error    switch (code) {      case 'ERR_NOT_FOUND':        return null      case 'ERR_RATE_LIMIT_EXCEEDED':        throw new Error(`Rate limited until ${body.error.resetAt}`)      case 'ERR_AUTH_MISSING':      case 'ERR_AUTH_INVALID':      case 'ERR_AUTH_REVOKED':        throw new Error(`Authentication failed: ${message}`)      default:        throw new Error(`API error ${res.status}: ${code}`)    }  }  return body.data}

استراتيجية إعادة المحاولة

ليس كل خطأ يستحق إعادة المحاولة. هذا هو مصفوفة إعادة المحاولة الموصى بها:

الخطأ / الحالةإعادة المحاولة؟الاستراتيجية
400 ERR_VALIDATIONNoأصلح معاملات الطلب.
401 ERR_AUTH_*Noأصلح مفتاح API.
403 ERR_PLAN_LIMITNoرقّ خطتك.
404 ERR_NOT_FOUNDNoالمورد غير موجود.
429 ERR_RATE_LIMITYesانتظر حتى الطابع الزمني X-RateLimit-Reset.
500 ERR_INTERNALYesتراجع أسي: 1 ثانية، 2 ثانية، 4 ثوانٍ، ثم فشل.
Network timeoutYesأعد المحاولة حتى 3 مرات مع تراجع.

إعادة المحاولة التلقائية في SDK

يعيد SDK تلقائياً محاولة أخطاء 500 وانتهاء مهلة الشبكة حتى maxRetries مرة (الافتراضي: 3) بالتراجع الأسي. لا يُعيد محاولة أخطاء 4xx.

تطبيق التراجع الأسي

عند استدعاء API مباشرةً (دون SDK)، طبّق التراجع الأسي للأخطاء القابلة للإعادة. هذا يتجنب إغراق API ويزيد فرصة النجاح:

retry.ts
async function fetchWithRetry(  url: string,  options: RequestInit,  maxRetries = 3,): Promise<Response> {  let attempt = 0  while (attempt <= maxRetries) {    const res = await fetch(url, options)    // Success or a non-retryable client error — return immediately    if (res.ok || (res.status >= 400 && res.status < 500 && res.status !== 429)) {      return res    }    // 429: honour the Retry-After / X-RateLimit-Reset header if present    if (res.status === 429) {      const resetHeader = res.headers.get('X-RateLimit-Reset')      const waitMs = resetHeader        ? Math.max(0, Number(resetHeader) * 1000 - Date.now())        : 2 ** attempt * 1000      console.warn(`Rate limited. Waiting ${waitMs}ms before retry ${attempt + 1}.`)      await new Promise((r) => setTimeout(r, waitMs))    } else {      // 5xx: exponential backoff — 1s, 2s, 4s, 8s …      const waitMs = 2 ** attempt * 1000      console.warn(`Server error ${res.status}. Waiting ${waitMs}ms before retry ${attempt + 1}.`)      await new Promise((r) => setTimeout(r, waitMs))    }    attempt++  }  throw new Error(`Request failed after ${maxRetries} retries`)}// Usageconst res = await fetchWithRetry(  'https://api.kalimalab.com/v1/words?letters=3',  { headers: { Authorization: `Bearer ${process.env.KALIMALAB_API_KEY}` } },)const { data } = await res.json()