ข้ามไปยังเนื้อหา
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_idID ของคำขอนี้ ตรงกับเฮดเดอร์การตอบกลับ 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ลองใหม่ ด้วย backoff แบบเอ็กซ์โพเนนเชียล: 1 วินาที 2 วินาที 4 วินาที… ไม่เกิน 1 นาที พร้อมการสุ่มเวลา (jitter)
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 ที่ไม่รู้จักให้ถือว่าเป็นปัญหาชั่วคราว