Hatalar
Sursa, bir isteğin başarılı olup olmadığını HTTP durum kodlarıyla, neden başarılı olmadığını ise değişmeyen bir hata koduyla bildirir. Tüm hata yanıtları aynı biçimdedir:
{
"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"
}
}
| Alan | Anlamı |
|---|---|
error.code | <area>.<reason> biçiminde değişmeyen kod. Kodunuzdaki dallanmayı buna göre yapın. |
error.message | Okunabilir İngilizce açıklama. Her an yeniden yazılabilir; bu metni ayrıştırmayın. |
error.details | Hatayla ilgili yapılandırılmış bilgiler: parametre, bir sınır ya da ne zaman yeniden deneneceği gibi. Alanları koda göre değişir. |
error.request_id | Bu isteğin kimliği; X-Request-Id yanıt başlığıyla aynıdır. |
error.doc_url | Bu portalda bu kodu anlatan sayfa. |
detail | Hatanın daha önceki biçimi; mevcut entegrasyonlar için korunur. Yeni kod error alanını okumalıdır. |
Her kodun Hata kodları altında kendi sayfası vardır: HTTP durumu, details alanları ve kodu döndüren uç
noktalar. API başvurusunda her uç noktanın sayfası, o uç noktanın döndürebileceği kodları listeler.
HTTP durumları
| Durum | Anlamı |
|---|---|
200, 201, 202, 204 | İstek başarılı oldu. 202, isteğin kabul edildiği ve hâlâ işlendiği anlamına gelir. |
400 | İstek hatalı biçimlendirilmiş: hatalı bir parametre, imleç, metadata ya da Idempotency-Key. İsteği düzeltin. |
401 | Geçerli bir anahtar yok. Kimlik doğrulama sayfasına bakın. |
402 | Kuruluşun planındaki bir sınıra ulaşıldı: örneğin kart sayısı ya da depolama alanı. |
403 | Anahtar geçerli, ancak bu işleme izin verilmiyor: bir rol, kapsam ya da plan özelliği eksik. |
404 | Nesne yok ya da anahtar bu nesneye erişemiyor. |
409 | İstek mevcut durumla çakışıyor: yinelenen bir external_id, açık bir senkronizasyon, aynı Idempotency-Key ile gönderilmiş ve hâlâ çalışan bir istek. |
410 | Nesnenin süresi dolmuş (örneğin 24 saati geçmiş bir yükleme) ya da yol kullanımdan kaldırılmış. |
413 | Gövde ya da dosya çok büyük. |
415 | Dosya türü desteklenmiyor ya da dosyanın içeriği adıyla uyuşmuyor. |
422 | İstek doğru biçimlendirilmiş, ancak geçersiz: eksik bir alan ya da izin verilen aralığın dışında bir değer. |
429 | Çok fazla istek gönderildi ya da bir kota tükendi. Hız sınırları ve kotalar sayfasına bakın. |
500, 502, 503, 504 | Sursa tarafında bir sorun var. Daha sonra yeniden deneyin. |
Geçerlilik hataları
validation.failed kodlu 422 yanıtında detail alanı, başarısız olan her alanı
konumuyla birlikte listeler:
{
"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…"}
}
Hangi hatalar yeniden denenmeli
| Hata | Yeniden denensin mi? |
|---|---|
| Ağ hatası ya da zaman aşımı, yanıt yok | Evet, aynı Idempotency-Key ile. |
429 | Evet, Retry-After başlığındaki saniye sayısı kadar bekledikten sonra. |
500, 502, 503, 504 | Evet, üstel geri çekilmeyle: 1 sn, 2 sn, 4 sn… bir dakikaya kadar, rastgele sapmayla. |
409 api.idempotency_in_progress | Evet, Retry-After süresinden sonra: bu anahtarla gönderilen ilk istek hâlâ çalışıyor. |
Diğer tüm 4xx | Hayır. Aynı istek yine başarısız olur; önce isteği düzeltin. |
POST ve PATCH isteklerini yalnızca bir Idempotency-Key ile yeniden deneyin;
böylece yanıtı kaybolan bir isteğin yeniden denenmesi ikinci bir nesne oluşturamaz. GET, PUT ve DELETE
istekleri olduğu gibi güvenle yeniden denenebilir.
// 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." }),
}),
);Sorun bildirme
Başarılı olsun ya da olmasın her yanıtta bir X-Request-Id başlığı bulunur ve her hatada aynı değer
error.request_id alanında yer alır. Bu değeri, isteğe ilişkin kendi kaydınızla birlikte günlüğe yazın. Bir istekle
ilgili olarak destek ekibine başvurduğunuzda isteğin kimliğini gönderin: bu kimlik doğrudan o isteğin kaydına götürür.
Bilmediğiniz kodları ele alma
API’nin her sürümünde yeni hata kodları ortaya çıkabilir. Bilinmeyen bir kodu HTTP durumuna göre ele alın: bilinmeyen
bir 4xx kodunu olduğu gibi başarılı olmayacak bir istek olarak, bilinmeyen bir 5xx kodunu geçici bir sorun olarak
değerlendirin.