मुख्य कंटेंट पर जाएँ
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इस रिक्वेस्ट की 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, 504Sursa की तरफ़ कोई समस्या। बाद में रीट्राई करें।

वैलिडेशन एरर

कोड validation.failed वाले 422 में 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हाँ, एक्सपोनेंशियल बैकऑफ़ (बढ़ते अंतराल) के साथ: 1 सेकंड, 2 सेकंड, 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 में होता है। इसे रिक्वेस्ट के अपने रिकॉर्ड के साथ लॉग करें। किसी रिक्वेस्ट के बारे में सपोर्ट से संपर्क करते समय उसकी रिक्वेस्ट ID भेजें: इससे सीधे उस रिक्वेस्ट के रिकॉर्ड तक पहुँचा जा सकता है।

अनजान कोड संभालना

API के किसी भी वर्शन में नए एरर कोड आ सकते हैं। अनजान कोड को उसके HTTP स्टेटस के आधार पर संभालें: अनजान 4xx को ऐसी रिक्वेस्ट मानें, जो जैसी है वैसी सफल नहीं होगी, और अनजान 5xx को अस्थायी समस्या।