Chyby
Sursa pomocí stavových kódů HTTP sděluje, zda požadavek uspěl, a pomocí stabilního chybového kódu, proč neuspěl. Každá chybová odpověď má stejný tvar:
{
"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"
}
}
| Pole | Význam |
|---|---|
error.code | Stabilní kód ve tvaru <area>.<reason>. Podle něj větvěte svůj kód. |
error.message | Čitelné vysvětlení v angličtině. Jeho znění se může kdykoli změnit; neparsujte ho. |
error.details | Strukturované údaje o chybě, například parametr, limit nebo kdy opakovat. Jeho pole závisejí na kódu. |
error.request_id | ID tohoto požadavku, stejné jako v hlavičce odpovědi X-Request-Id. |
error.doc_url | Stránka o tomto kódu na tomto portálu. |
detail | Dřívější podoba chyby, zachovaná kvůli stávajícím integracím. Nový kód by měl číst error. |
Každý kód má vlastní stránku v sekci Chybové kódy se stavovým kódem HTTP, poli details a operacemi,
které ho vracejí. Stránka každé operace v referenci API uvádí kódy, které tato operace může vrátit.
Stavové kódy HTTP
| Stavový kód | Význam |
|---|---|
200, 201, 202, 204 | Požadavek uspěl. 202 znamená, že byl přijat a stále se zpracovává. |
400 | Požadavek je chybně sestavený: špatný parametr, kurzor, metadata nebo Idempotency-Key. Opravte požadavek. |
401 | Chybí platný klíč. Viz Autentizace. |
402 | Organizace dosáhla limitu svého tarifu, například počtu karet nebo úložiště. |
403 | Klíč je platný, ale tuto akci provést nesmí: chybí role, rozsah nebo funkce tarifu. |
404 | Objekt neexistuje, nebo ho klíč nesmí vidět. |
409 | Požadavek je v rozporu s aktuálním stavem: duplicitní external_id, otevřená synchronizace, stále běžící požadavek se stejným Idempotency-Key. |
410 | Objektu vypršela platnost, například nahrávání po 24 hodinách, nebo byla cesta vyřazena z provozu. |
413 | Tělo požadavku nebo soubor přesahuje povolenou velikost. |
415 | Typ souboru není podporovaný, nebo jeho obsah neodpovídá názvu. |
422 | Požadavek je správně sestavený, ale neplatný: chybí pole nebo je hodnota mimo rozsah. |
429 | Příliš mnoho požadavků nebo vyčerpaná kvóta. Viz Limity četnosti a kvóty. |
500, 502, 503, 504 | Problém na straně Sursy. Zopakujte požadavek později. |
Chyby validace
U 422 s kódem validation.failed uvádí detail každé pole, které validací
neprošlo, spolu s jeho umístěním:
{
"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…"}
}
Které chyby opakovat
| Chyba | Opakovat? |
|---|---|
| Chyba sítě nebo vypršení časového limitu, žádná odpověď | Ano, se stejným Idempotency-Key. |
429 | Ano, po počtu sekund uvedeném v Retry-After. |
500, 502, 503, 504 | Ano, s exponenciálně rostoucí prodlevou: 1 s, 2 s, 4 s… až do minuty, s náhodným rozptylem. |
409 api.idempotency_in_progress | Ano, po Retry-After: první požadavek s tímto klíčem stále běží. |
Jakýkoli jiný 4xx | Ne. Stejný požadavek znovu selže; nejdřív ho opravte. |
Požadavky POST a PATCH opakujte jen s Idempotency-Key, aby opakování po
ztracené odpovědi nemohlo vytvořit druhý objekt. GET, PUT a DELETE lze bezpečně opakovat tak, jak jsou.
// 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." }),
}),
);Hlášení problému
Každá odpověď, úspěšná i neúspěšná, má hlavičku X-Request-Id a každá chyba má stejnou hodnotu
v error.request_id. Zapisujte ji do protokolu spolu s vlastním záznamem požadavku. Když se kvůli požadavku
obracíte na podporu, pošlete jeho ID: vede přímo k záznamu tohoto požadavku.
Zpracování neznámých kódů
Nové chybové kódy se mohou objevit v jakékoli verzi API. S neznámým kódem zacházejte podle jeho stavového kódu HTTP:
s neznámým 4xx jako s požadavkem, který v této podobě neuspěje, s neznámým 5xx jako s dočasným problémem.