Gå til indholdet
Sursa Developers

Fejl

Sursa bruger HTTP-statuskoder til at angive, om en anmodning lykkedes, og en stabil fejlkode til at angive, hvorfor den ikke gjorde. Alle fejlsvar har samme form:

{
  "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"
  }
}
FeltBetydning
error.codeStabil kode i formen <area>.<reason>. Lad din kode forgrene sig efter den.
error.messageEn læsbar forklaring på engelsk. Den kan omformuleres når som helst; fortolk den ikke.
error.detailsStrukturerede oplysninger om fejlen, fx parameteren, en grænse eller hvornår du kan forsøge igen. Felterne afhænger af koden.
error.request_idId’et for denne anmodning, det samme som i svarheaderen X-Request-Id.
error.doc_urlSiden om denne kode på portalen.
detailDen tidligere form af fejlen, bevaret for eksisterende integrationer. Ny kode bør læse error.

Hver kode har sin egen side under Fejlkoder med dens HTTP-status, felterne i details og de operationer, der returnerer den. Siden for hver operation i API-referencen viser de koder, operationen kan returnere.

HTTP-statusser

StatusBetydning
200, 201, 202, 204Anmodningen lykkedes. 202 betyder, at den er modtaget og stadig behandles.
400Anmodningen er forkert udformet: en forkert parameter, cursor, metadata eller Idempotency-Key. Ret anmodningen.
401Ingen gyldig nøgle. Se Autentificering.
402En grænse i organisationens prisplan er nået, fx antallet af kort eller lagerpladsen.
403Nøglen er gyldig, men har ikke lov til dette: Der mangler en rolle, et scope eller en funktion i prisplanen.
404Objektet findes ikke, eller nøglen har ikke lov til at se det.
409Anmodningen er i konflikt med den aktuelle tilstand: et external_id, der allerede findes, en åben synkronisering, en anmodning med den samme Idempotency-Key, der stadig kører.
410Objektet er udløbet, fx en upload efter 24 timer, eller ruten er udfaset.
413Brødteksten eller filen er for stor.
415Filtypen understøttes ikke, eller indholdet passer ikke til filnavnet.
422Anmodningen er korrekt udformet, men ugyldig: et manglende felt eller en værdi uden for det tilladte interval.
429For mange anmodninger, eller en kvote er brugt op. Se Hastighedsgrænser og kvoter.
500, 502, 503, 504Et problem hos Sursa. Forsøg igen senere.

Valideringsfejl

Ved 422 med koden validation.failed viser detail alle felter, der ikke bestod valideringen, hver med sin placering:

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

Hvilke fejl du skal forsøge igen

FejlForsøge igen?
Netværksfejl eller timeout, intet svarJa, med den samme Idempotency-Key.
429Ja, efter det antal sekunder, der står i Retry-After.
500, 502, 503, 504Ja, med eksponentiel backoff: 1 s, 2 s, 4 s … op til et minut, med tilfældig jitter.
409 api.idempotency_in_progressJa, efter Retry-After: Den første anmodning med denne nøgle kører stadig.
Enhver anden 4xxNej. Den samme anmodning vil mislykkes igen; ret den først.

Forsøg kun POST- og PATCH-anmodninger igen med en Idempotency-Key, så et nyt forsøg efter et tabt svar ikke kan oprette et objekt mere. GET, PUT og DELETE kan trygt forsøges igen, som de er.

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

Rapportering af et problem

Hvert svar, vellykket eller ej, har en X-Request-Id-header, og hver fejl har den samme værdi i error.request_id. Log den sammen med din egen registrering af anmodningen. Når du kontakter support om en anmodning, så send anmodningens id: Det fører direkte til registreringen af netop den anmodning.

Håndtering af koder, du ikke kender

Nye fejlkoder kan dukke op i enhver version af API’et. Behandl en ukendt kode ud fra dens HTTP-status: en ukendt 4xx som en anmodning, der ikke vil lykkes, som den er, og en ukendt 5xx som et midlertidigt problem.