انتقل إلى المحتوى
Sursa Developers

الأخطاء

يستخدم Sursa رموز حالة HTTP ليبيّن هل نجح الطلب، ورمز خطأ ثابتًا ليبيّن سبب عدم نجاحه. ولكل استجابات الأخطاء الشكل نفسه:

{
  "detail": "the cursor is malformed or was issued for different filters",
  "error": {
    "code": "api.cursor_invalid",
    "message": "the cursor is malformed or was issued for different filters",
    "details": {"parameter": "cursor"},
    "request_id": "01JB7Q2M4X9V3K8T5N6P0R1S2A",
    "doc_url": "https://developers.sursa.com/errors/api.cursor_invalid"
  }
}
الحقلالمعنى
error.codeرمز ثابت بالصيغة <area>.<reason>. ابنِ منطق شيفرتك عليه.
error.messageشرح مقروء بالإنجليزية. قد تتغيّر صياغته في أي وقت، فلا تحلّله.
error.detailsمعلومات منظمة عن الخطأ، مثل المعامل، أو حد، أو موعد إعادة المحاولة. وتعتمد حقوله على الرمز.
error.request_idمعرّف هذا الطلب، وهو نفسه في ترويسة الاستجابة X-Request-Id.
error.doc_urlصفحة هذا الرمز في هذه البوابة.
detailالشكل الأقدم للخطأ، محفوظ للتكاملات القائمة. وعلى الشيفرة الجديدة قراءة error.

لكل رمز صفحته الخاصة في رموز الأخطاء، مع حالة HTTP وحقول details ونقاط النهاية التي تعيده. وتسرد صفحة كل نقطة نهاية في مرجع API الرموز التي قد تعيدها.

حالات HTTP

الحالةالمعنى
200، 201، 202، 204نجح الطلب. وتعني 202 أن الطلب قُبل ولا تزال معالجته جارية.
400الطلب مشوّه: معامل أو مؤشر أو metadata أو Idempotency-Key غير صالح. أصلح الطلب.
401لا مفتاح صالحًا. انظر المصادقة.
402بلغت المؤسسة أحد حدود خطتها، مثل عدد البطاقات أو مساحة التخزين.
403المفتاح صالح لكنه غير مسموح له بهذا: ينقصه دور أو نطاق صلاحيات أو ميزة في الخطة.
404الكائن غير موجود، أو لا يُسمح للمفتاح برؤيته.
409الطلب يتعارض مع الحالة الحالية: قيمة external_id مكررة، أو مزامنة مفتوحة، أو طلب بالقيمة Idempotency-Key نفسها لا يزال قيد التنفيذ.
410انتهت صلاحية الكائن، مثل عملية رفع بعد 24 ساعة، أو أُوقف المسار.
413النص أو الملف كبير جدًا.
415نوع الملف غير مدعوم، أو محتواه لا يطابق اسمه.
422الطلب سليم الشكل لكنه غير صالح: حقل ناقص أو قيمة خارج المدى المسموح.
429طلبات كثيرة جدًا أو استُنفدت حصة. انظر حدود معدل الطلبات والحصص.
500، 502، 503، 504مشكلة من جهة Sursa. أعد المحاولة لاحقًا.

أخطاء صحة البيانات

في الحالة 422 مع الرمز validation.failed، يسرد الحقل detail كل حقل لم يجتز التحقق، ومع كل منها موضعه:

{
  "detail": [
    {"loc": ["body", "title"], "msg": "String should have at least 1 character", "type": "string_too_short"}
  ],
  "error": {"code": "validation.failed", "message": "request validation failed", "request_id": "01JB7…"}
}

الأخطاء التي تُعاد المحاولة عندها

الخطأهل تُعاد المحاولة؟
خطأ في الشبكة أو انتهاء المهلة، بلا استجابةنعم، بالقيمة Idempotency-Key نفسها.
429نعم، بعد عدد الثواني المذكور في Retry-After.
500، 502، 503، 504نعم، مع تراجع أُسّي: ثانية واحدة، ثم ثانيتان، ثم 4 ثوانٍ… حتى دقيقة، مع تشتيت عشوائي.
409 api.idempotency_in_progressنعم، بعد Retry-After: الطلب الأول بهذا المفتاح لا يزال قيد التنفيذ.
أي حالة 4xx أخرىلا. الطلب نفسه سيفشل مجددًا؛ أصلحه أولًا.

لا تُعِد محاولة طلبات POST وPATCH إلا مع الترويسة Idempotency-Key، كي لا تنشئ إعادة المحاولة بعد ضياع الاستجابة كائنًا ثانيًا. أما GET وPUT وDELETE فإعادة محاولتها آمنة كما هي.

// Retries a request on network errors, 429 and 5xx. The same Idempotency-Key is sent on every attempt.
async function withRetries(send, attempts = 5) {
  for (let attempt = 1; ; attempt++) {
    let response;
    try {
      response = await send();
    } catch (error) {
      if (attempt >= attempts) throw error;
    }
    if (response && response.status !== 429 && response.status < 500) return response;
    if (attempt >= attempts) return response;
    const retryAfter = Number(response?.headers.get("Retry-After"));
    const backoff = Math.min(60, 2 ** (attempt - 1)) * (0.8 + Math.random() * 0.4);
    await new Promise((resolve) => setTimeout(resolve, 1000 * (retryAfter || backoff)));
  }
}

const key = crypto.randomUUID();
const response = await withRetries(() =>
  fetch("https://api.sursa.com/v1/cards/text", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.SURSA_API_KEY}`,
      "Content-Type": "application/json",
      "Idempotency-Key": key,
    },
    body: JSON.stringify({ title: "Refund policy", body_markdown: "Refunds take 14 days." }),
  }),
);

الإبلاغ عن مشكلة

لكل استجابة، ناجحة أو لا، ترويسة X-Request-Id، ولكل خطأ القيمة نفسها في error.request_id. سجّلها مع سجلك الخاص للطلب. وحين تتواصل مع الدعم بشأن طلب، أرسل معرّف الطلب: فهو يقود مباشرة إلى سجل ذلك الطلب.

التعامل مع الرموز المجهولة

قد تظهر رموز أخطاء جديدة في أي إصدار من واجهة API. تعامل مع الرمز المجهول حسب حالة HTTP: الحالة 4xx المجهولة طلب لن ينجح كما هو، والحالة 5xx المجهولة مشكلة مؤقتة.