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"
}
}
| Laukas | Reikšmė |
|---|---|
error.code | Pastovus 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.details | Struktū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ą. |
detail | Ankstesnė 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ūsena | Reikšmė |
|---|---|
200, 201, 202, 204 | Užklausa pavyko. 202 reiškia, kad ji priimta ir dar apdorojama. |
400 | Užklausa netinkamai suformuota: netinkamas parametras, žymeklis, metadata arba Idempotency-Key. Pataisykite užklausą. |
401 | Nėra galiojančio rakto. Žr. Autentifikavimas. |
402 | Pasiektas organizacijos plano limitas, pavyzdžiui, kortelių skaičiaus ar saugyklos. |
403 | Raktas galioja, bet jam neleidžiama to daryti: trūksta vaidmens, apimties arba plano funkcijos. |
404 | Objekto nėra arba raktui neleidžiama jo matyti. |
409 | Užklausa prieštarauja dabartinei būsenai: pasikartojantis external_id, atidaryta sinchronizacija, dar vykdoma užklausa su tuo pačiu Idempotency-Key. |
410 | Objekto galiojimas baigėsi, pavyzdžiui, įkėlimo po 24 valandų, arba maršrutas panaikintas. |
413 | Turinys arba failas per didelis. |
415 | Failo tipas nepalaikomas arba jo turinys neatitinka pavadinimo. |
422 | Užklausa suformuota tinkamai, bet negaliojanti: trūksta lauko arba reikšmė už leistino intervalo. |
429 | Per daug užklausų arba išnaudota kvota. Žr. Užklausų dažnio limitai ir kvotos. |
500, 502, 503, 504 | Problema 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
| Klaida | Kartoti? |
|---|---|
| Tinklo klaida arba baigėsi laiko limitas, atsako nėra | Taip, su tuo pačiu Idempotency-Key. |
429 | Taip, po tiek sekundžių, kiek nurodyta Retry-After. |
500, 502, 503, 504 | Taip, su eksponentiškai ilgėjančiomis pauzėmis: 1 s, 2 s, 4 s… iki minutės, su atsitiktiniu nuokrypiu. |
409 api.idempotency_in_progress | Taip, po Retry-After: pirmoji užklausa su šiuo raktu dar vykdoma. |
Bet kuri kita 4xx | Ne. 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ą.