Pereiti prie turinio
Sursa Developers

Klaidos

Sursa HTTP būsenos kodais praneša, ar užklausa pavyko, o pastoviu klaidos kodu – kodėl nepavyko. Visi klaidų atsakai yra tos pačios formos:

{
  "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"
  }
}
LaukasReikšmė
error.codePastovus kodas, kurio forma <area>.<reason>. Savo kode remkitės juo.
error.messageŽmogui skirtas paaiškinimas anglų kalba. Jo formuluotė gali bet kada pasikeisti; jo neanalizuokite.
error.detailsStruktūrizuoti klaidos faktai, pavyzdžiui, parametras, limitas ar kada kartoti. Jo laukai priklauso nuo kodo.
error.request_idŠios užklausos ID, toks pat kaip atsako antraštėje X-Request-Id.
error.doc_urlŠio portalo puslapis apie šį kodą.
detailAnkstesnė klaidos forma, palikta esamoms integracijoms. Naujas kodas turėtų skaityti error.

Kiekvienas kodas turi savo puslapį skiltyje Klaidų kodai su HTTP būsena, details laukais ir operacijomis, kurios jį grąžina. Kiekvienos operacijos puslapyje API žinyne išvardyti kodai, kuriuos ta operacija gali grąžinti.

HTTP būsenos

BūsenaReikšmė
200, 201, 202, 204Užklausa pavyko. 202 reiškia, kad ji priimta ir dar apdorojama.
400Užklausa netinkamai suformuota: netinkamas parametras, žymeklis, metadata arba Idempotency-Key. Pataisykite užklausą.
401Nėra galiojančio rakto. Žr. Autentifikavimas.
402Pasiektas organizacijos plano limitas, pavyzdžiui, kortelių skaičiaus ar saugyklos.
403Raktas galioja, bet jam neleidžiama to daryti: trūksta vaidmens, apimties arba plano funkcijos.
404Objekto nėra arba raktui neleidžiama jo matyti.
409Užklausa prieštarauja dabartinei būsenai: pasikartojantis external_id, atidaryta sinchronizacija, dar vykdoma užklausa su tuo pačiu Idempotency-Key.
410Objekto galiojimas baigėsi, pavyzdžiui, įkėlimo po 24 valandų, arba maršrutas panaikintas.
413Turinys arba failas per didelis.
415Failo tipas nepalaikomas arba jo turinys neatitinka pavadinimo.
422Užklausa suformuota tinkamai, bet negaliojanti: trūksta lauko arba reikšmė už leistino intervalo.
429Per daug užklausų arba išnaudota kvota. Žr. Užklausų dažnio limitai ir kvotos.
500, 502, 503, 504Problema Sursos pusėje. Pakartokite vėliau.

Validavimo klaidos

Atsako 422 su kodu validation.failed lauke detail išvardyti visi validavimo nepraėję laukai, kiekvienas su savo vieta:

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

Kurias klaidas kartoti

KlaidaKartoti?
Tinklo klaida arba baigėsi laiko limitas, atsako nėraTaip, su tuo pačiu Idempotency-Key.
429Taip, po tiek sekundžių, kiek nurodyta Retry-After.
500, 502, 503, 504Taip, su eksponentiškai ilgėjančiomis pauzėmis: 1 s, 2 s, 4 s… iki minutės, su atsitiktiniu nuokrypiu.
409 api.idempotency_in_progressTaip, po Retry-After: pirmoji užklausa su šiuo raktu dar vykdoma.
Bet kuri kita 4xxNe. Ta pati užklausa vėl nepavyks; pirmiausia ją pataisykite.

POST ir PATCH užklausas kartokite tik su Idempotency-Key, kad pakartojimas dingus atsakui negalėtų sukurti antro objekto. GET, PUT ir DELETE užklausas saugu kartoti tokias, kokios yra.

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

Kaip pranešti apie problemą

Kiekvienas atsakas, sėkmingas ar ne, turi antraštę X-Request-Id, o kiekviena klaida tą pačią reikšmę turi lauke error.request_id. Įrašykite ją į žurnalą kartu su savo užklausos įrašu. Kai kreipiatės į pagalbos tarnybą dėl užklausos, nurodykite jos ID: pagal jį iškart randamas tos užklausos įrašas.

Nežinomi kodai

Nauji klaidų kodai gali atsirasti bet kurioje API versijoje. Nežinomą kodą vertinkite pagal HTTP būseną: nežinomą 4xx – kaip užklausą, kuri tokia, kokia yra, nepavyks, nežinomą 5xx – kaip laikiną problemą.