Preskoči na sadržaj
Sursa Developers

Pogreške

Sursa koristi HTTP statusne kodove da bi rekla je li zahtjev uspio, a stabilan kod pogreške da bi rekla zašto nije uspio. Svaki odgovor s pogreškom ima isti oblik:

{
  "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"
  }
}
PoljeZnačenje
error.codeStabilan kod u obliku <area>.<reason>. Na njemu granajte svoj kod.
error.messageČitljivo objašnjenje na engleskom. Može se u bilo kojem trenutku preformulirati; ne raščlanjujte ga.
error.detailsStrukturirane činjenice o pogrešci, kao što su parametar, ograničenje ili kad ponovno pokušati. Njegova polja ovise o kodu.
error.request_idID ovog zahtjeva, isti kao u zaglavlju odgovora X-Request-Id.
error.doc_urlStranica o ovom kodu na ovom portalu.
detailRaniji oblik pogreške, zadržan zbog postojećih integracija. Novi kod treba čitati error.

Svaki kod ima vlastitu stranicu u odjeljku Kodovi pogrešaka, s HTTP statusom, poljima objekta details i operacijama koje ga vraćaju. Stranica svake operacije u referenci API-ja navodi kodove koje ta operacija može vratiti.

HTTP statusi

StatusZnačenje
200, 201, 202, 204Zahtjev je uspio. 202 znači da je zahtjev prihvaćen i da se još obrađuje.
400Zahtjev je neispravno oblikovan: pogrešan parametar, kursor, metadata ili Idempotency-Key. Ispravite zahtjev.
401Nema valjanog ključa. V. Autentifikacija.
402Dosegnuto je ograničenje plana organizacije, kao što je broj kartica ili prostor za pohranu.
403Ključ je valjan, ali to ne smije učiniti: nedostaje uloga, opseg ili mogućnost plana.
404Objekt ne postoji ili ga ključ ne smije vidjeti.
409Zahtjev je u sukobu s trenutačnim stanjem: dvostruki external_id, otvorena sinkronizacija, zahtjev s istim Idempotency-Key koji se još izvršava.
410Objekt je istekao, primjerice učitavanje nakon 24 sata, ili je ruta ukinuta.
413Tijelo ili datoteka su preveliki.
415Vrsta datoteke nije podržana ili njezin sadržaj ne odgovara njezinu imenu.
422Zahtjev je ispravno oblikovan, ali nije valjan: nedostaje polje ili je vrijednost izvan raspona.
429Previše zahtjeva ili je kvota potrošena. V. Ograničenja učestalosti i kvote.
500, 502, 503, 504Problem na strani Surse. Pokušajte ponovno kasnije.

Pogreške provjere valjanosti

Za 422 s kodom validation.failed detail navodi svako polje koje nije prošlo provjeru, svako s njegovim mjestom:

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

Koje pogreške treba ponovno pokušati

PogreškaPonovno pokušati?
Mrežna pogreška ili istek vremena, nema odgovoraDa, s istim Idempotency-Key.
429Da, nakon broja sekundi navedenog u Retry-After.
500, 502, 503, 504Da, s eksponencijalno rastućom stankom: 1 s, 2 s, 4 s… do jedne minute, uz nasumično odstupanje (jitter).
409 api.idempotency_in_progressDa, nakon Retry-After: prvi zahtjev s ovim ključem još se izvršava.
Bilo koji drugi 4xxNe. Isti zahtjev ponovno neće uspjeti; najprije ga ispravite.

Zahtjeve POST i PATCH ponovno pokušavajte samo s Idempotency-Key, kako ponovni pokušaj nakon izgubljenog odgovora ne bi mogao stvoriti drugi objekt. GET, PUT i DELETE sigurno je ponovno pokušati takve kakvi jesu.

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

Prijava problema

Svaki odgovor, uspješan ili ne, ima zaglavlje X-Request-Id, a svaka pogreška ima istu vrijednost u error.request_id. Zapišite je uz vlastiti zapis o zahtjevu. Kad se obraćate podršci zbog nekog zahtjeva, pošaljite njegov ID zahtjeva: on vodi izravno do zapisa o tom zahtjevu.

Obrada nepoznatih kodova

Novi kodovi pogrešaka mogu se pojaviti u bilo kojoj verziji API-ja. Nepoznati kod obrađujte prema njegovu HTTP statusu: nepoznati 4xx kao zahtjev koji u tom obliku neće uspjeti, nepoznati 5xx kao privremeni problem.