Chuyển tới nội dung
Sursa Developers

Lỗi

Sursa dùng mã trạng thái HTTP để cho biết yêu cầu có thành công hay không, và một mã lỗi ổn định để cho biết vì sao không thành công. Mọi phản hồi lỗi có cùng một cấu trúc:

{
  "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"
  }
}
TrườngÝ nghĩa
error.codeMã ổn định dạng <area>.<reason>. Hãy rẽ nhánh mã của bạn theo trường này.
error.messageLời giải thích dễ đọc bằng tiếng Anh. Nó có thể được viết lại bất cứ lúc nào; đừng phân tích nó.
error.detailsCác dữ kiện có cấu trúc về lỗi, chẳng hạn tham số, một giới hạn, hoặc khi nào nên thử lại. Các trường của nó phụ thuộc vào mã.
error.request_idID của yêu cầu này, giống header phản hồi X-Request-Id.
error.doc_urlTrang về mã này trên cổng này.
detailDạng lỗi trước đây, được giữ lại cho các tích hợp hiện có. Mã mới nên đọc error.

Mỗi mã có trang riêng trong Mã lỗi, với trạng thái HTTP, các trường của details và các endpoint trả về nó. Trang của mỗi endpoint trong tài liệu tham chiếu API liệt kê các mã mà endpoint đó có thể trả về.

Trạng thái HTTP

Trạng tháiÝ nghĩa
200, 201, 202, 204Yêu cầu thành công. 202 nghĩa là yêu cầu đã được chấp nhận và vẫn đang được xử lý.
400Yêu cầu sai định dạng: tham số, con trỏ, metadata hoặc Idempotency-Key không đúng. Hãy sửa yêu cầu.
401Không có khóa hợp lệ. Xem Xác thực.
402Đã chạm một giới hạn của gói của tổ chức, chẳng hạn số lượng thẻ hoặc dung lượng lưu trữ.
403Khóa hợp lệ nhưng không được phép làm việc này: thiếu vai trò, phạm vi quyền hoặc tính năng của gói.
404Đối tượng không tồn tại, hoặc khóa không được phép xem nó.
409Yêu cầu xung đột với trạng thái hiện tại: external_id bị trùng, một phiên đồng bộ đang mở, một yêu cầu với cùng Idempotency-Key vẫn đang chạy.
410Đối tượng đã hết hạn, chẳng hạn một lượt tải lên sau 24 giờ, hoặc tuyến API đã ngừng hoạt động.
413Phần thân hoặc tệp quá lớn.
415Loại tệp không được hỗ trợ, hoặc nội dung tệp không khớp với tên của nó.
422Yêu cầu đúng định dạng nhưng không hợp lệ: thiếu trường hoặc giá trị nằm ngoài khoảng cho phép.
429Quá nhiều yêu cầu hoặc đã dùng hết hạn mức. Xem Giới hạn tốc độ và hạn mức.
500, 502, 503, 504Sự cố phía Sursa. Hãy thử lại sau.

Lỗi dữ liệu không hợp lệ

Với 422 và mã validation.failed, detail liệt kê mọi trường không hợp lệ, mỗi trường kèm vị trí của nó:

{
  "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…"}
}

Lỗi nào nên thử lại

LỗiThử lại?
Lỗi mạng hoặc hết thời gian chờ, không có phản hồiCó, với cùng Idempotency-Key.
429Có, sau số giây ghi trong Retry-After.
500, 502, 503, 504Có, với backoff lũy thừa (khoảng chờ tăng dần): 1 giây, 2 giây, 4 giây… tối đa một phút, kèm jitter (độ lệch ngẫu nhiên).
409 api.idempotency_in_progressCó, sau Retry-After: yêu cầu đầu tiên với khóa này vẫn đang chạy.
Mọi 4xx khácKhông. Cùng yêu cầu đó sẽ lại thất bại; hãy sửa nó trước.

Chỉ thử lại yêu cầu POST và PATCH khi có Idempotency-Key, để lần thử lại sau khi mất phản hồi không thể tạo ra đối tượng thứ hai. GET, PUT và DELETE có thể thử lại nguyên trạng một cách an toàn.

// 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." }),
  }),
);

Báo cáo sự cố

Mọi phản hồi, thành công hay không, đều có header X-Request-Id, và mọi lỗi có cùng giá trị đó trong error.request_id. Hãy ghi nó vào nhật ký cùng bản ghi của bạn về yêu cầu. Khi liên hệ bộ phận hỗ trợ về một yêu cầu, hãy gửi ID yêu cầu của nó: ID này dẫn thẳng tới bản ghi của yêu cầu đó.

Xử lý các mã bạn không biết

Mã lỗi mới có thể xuất hiện trong bất kỳ phiên bản nào của API. Hãy xử lý mã không xác định theo trạng thái HTTP của nó: một 4xx không xác định là yêu cầu sẽ không thành công nếu giữ nguyên, một 5xx không xác định là sự cố tạm thời.