Siirry sisältöön
Sursa Developers

Virheet

Sursa kertoo HTTP-tilakoodilla, onnistuiko pyyntö, ja pysyvällä virhekoodilla, miksi se ei onnistunut. Jokaisella virhevastauksella on sama rakenne:

{
  "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"
  }
}
KenttäMerkitys
error.codePysyvä koodi muodossa <area>.<reason>. Haarauta koodisi toiminta sen mukaan.
error.messageLuettava englanninkielinen selitys. Sen sanamuoto voi muuttua milloin tahansa; älä jäsennä sitä.
error.detailsJäsennellyt tiedot virheestä, kuten parametri, raja tai milloin kannattaa yrittää uudelleen. Sen kentät riippuvat koodista.
error.request_idTämän pyynnön tunnus, sama kuin X-Request-Id-vastausotsakkeessa.
error.doc_urlTämän koodin sivu tässä portaalissa.
detailVirheen aiempi muoto, joka on säilytetty olemassa olevia integraatioita varten. Uuden koodin kannattaa lukea error.

Jokaisella koodilla on oma sivunsa kohdassa Virhekoodit: sen HTTP-tila, details-kentät ja päätepisteet, jotka palauttavat sen. API-viitteen jokaisen päätepisteen sivulla luetellaan koodit, jotka kyseinen päätepiste voi palauttaa.

HTTP-tilat

TilaMerkitys
200, 201, 202, 204Pyyntö onnistui. 202 tarkoittaa, että pyyntö on hyväksytty ja sen käsittely on vielä kesken.
400Pyyntö on muodostettu virheellisesti: virheellinen parametri, kursori, metadata tai Idempotency-Key. Korjaa pyyntö.
401Kelvollista avainta ei ole. Ks. Todennus.
402Organisaation paketin raja on saavutettu, esimerkiksi korttien määrä tai tallennustila.
403Avain on kelvollinen, mutta sillä ei ole lupaa tähän: rooli, käyttöalue tai paketin ominaisuus puuttuu.
404Objektia ei ole olemassa, tai avain ei saa nähdä sitä.
409Pyyntö on ristiriidassa nykyisen tilan kanssa: toistuva external_id, avoin synkronointi tai samalla Idempotency-Key-otsakkeella tehty pyyntö, joka on vielä käynnissä.
410Objektin voimassaolo on päättynyt, kuten latauksen 24 tunnin jälkeen, tai reitti on poistettu käytöstä.
413Runko tai tiedosto on liian suuri.
415Tiedostotyyppiä ei tueta, tai tiedoston sisältö ei vastaa sen nimeä.
422Pyyntö on muodostettu oikein, mutta se on virheellinen: kenttä puuttuu tai arvo on sallitun alueen ulkopuolella.
429Liian monta pyyntöä, tai kiintiö on käytetty. Ks. Nopeusrajoitukset ja kiintiöt.
500, 502, 503, 504Ongelma Sursan puolella. Yritä myöhemmin uudelleen.

Validointivirheet

Kun vastaus on 422 ja koodi validation.failed, detail luettelee jokaisen virheellisen kentän ja sen sijainnin:

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

Mitkä virheet kannattaa yrittää uudelleen

VirheYritetäänkö uudelleen?
Verkkovirhe tai aikakatkaisu, ei vastaustaKyllä, samalla Idempotency-Key-otsakkeella.
429Kyllä, kun Retry-After-otsakkeen ilmoittamat sekunnit ovat kuluneet.
500, 502, 503, 504Kyllä, eksponentiaalisella odotuksella: 1 s, 2 s, 4 s… enintään minuuttiin asti, satunnaishajonnalla.
409 api.idempotency_in_progressKyllä, Retry-After-ajan jälkeen: ensimmäinen pyyntö tällä avaimella on vielä käynnissä.
Mikä tahansa muu 4xxEi. Sama pyyntö epäonnistuu uudelleen; korjaa se ensin.

Yritä POST- ja PATCH-pyyntöjä uudelleen vain Idempotency-Key-otsakkeen kanssa, jotta kadonneen vastauksen jälkeinen uusintayritys ei voi luoda toista objektia. GET, PUT ja DELETE ovat turvallisia yrittää uudelleen sellaisinaan.

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

Ongelmasta ilmoittaminen

Jokaisessa vastauksessa, onnistuneessa tai epäonnistuneessa, on X-Request-Id-otsake, ja jokaisessa virheessä on sama arvo error.request_id-kentässä. Kirjaa se lokiin oman pyyntömerkintäsi yhteyteen. Kun otat yhteyttä tukeen jostakin pyynnöstä, lähetä sen pyyntötunnus: se johtaa suoraan kyseisen pyynnön merkintään.

Tuntemattomien koodien käsittely

Uusia virhekoodeja voi ilmestyä mihin tahansa API:n versioon. Käsittele tuntematon koodi sen HTTP-tilan mukaan: tuntematon 4xx pyyntönä, joka ei onnistu sellaisenaan, ja tuntematon 5xx tilapäisenä ongelmana.