Přejít na obsah
Sursa Developers

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"
  }
}
PoleVýznam
error.codeStabilní 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.detailsStrukturované údaje o chybě, například parametr, limit nebo kdy opakovat. Jeho pole závisejí na kódu.
error.request_idID tohoto požadavku, stejné jako v hlavičce odpovědi X-Request-Id.
error.doc_urlStránka o tomto kódu na tomto portálu.
detailDří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ódVýznam
200, 201, 202, 204Požadavek uspěl. 202 znamená, že byl přijat a stále se zpracovává.
400Požadavek je chybně sestavený: špatný parametr, kurzor, metadata nebo Idempotency-Key. Opravte požadavek.
401Chybí platný klíč. Viz Autentizace.
402Organizace dosáhla limitu svého tarifu, například počtu karet nebo úložiště.
403Klíč je platný, ale tuto akci provést nesmí: chybí role, rozsah nebo funkce tarifu.
404Objekt neexistuje, nebo ho klíč nesmí vidět.
409Pož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.
410Objektu vypršela platnost, například nahrávání po 24 hodinách, nebo byla cesta vyřazena z provozu.
413Tělo požadavku nebo soubor přesahuje povolenou velikost.
415Typ souboru není podporovaný, nebo jeho obsah neodpovídá názvu.
422Požadavek je správně sestavený, ale neplatný: chybí pole nebo je hodnota mimo rozsah.
429Příliš mnoho požadavků nebo vyčerpaná kvóta. Viz Limity četnosti a kvóty.
500, 502, 503, 504Problé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

ChybaOpakovat?
Chyba sítě nebo vypršení časového limitu, žádná odpověďAno, se stejným Idempotency-Key.
429Ano, po počtu sekund uvedeném v Retry-After.
500, 502, 503, 504Ano, s exponenciálně rostoucí prodlevou: 1 s, 2 s, 4 s… až do minuty, s náhodným rozptylem.
409 api.idempotency_in_progressAno, po Retry-After: první požadavek s tímto klíčem stále běží.
Jakýkoli jiný 4xxNe. 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.