Zum Inhalt springen
Sursa Developers

Fehler

Sursa zeigt mit HTTP-Statuscodes, ob eine Anfrage erfolgreich war, und mit einem stabilen Fehlercode, warum nicht. Jede Fehlerantwort hat dieselbe 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"
  }
}
FeldBedeutung
error.codeStabiler Code in der Form <area>.<reason>. Verzweigen Sie Ihren Code danach.
error.messageEine lesbare Erklärung auf Englisch. Der Text kann jederzeit umformuliert werden; werten Sie ihn nicht aus.
error.detailsStrukturierte Angaben zum Fehler, etwa der Parameter, ein Limit oder wann ein erneuter Versuch möglich ist. Die Felder hängen vom Code ab.
error.request_idDie ID dieser Anfrage, dieselbe wie im Antwort-Header X-Request-Id.
error.doc_urlDie Seite zu diesem Code in diesem Portal.
detailDie frühere Form des Fehlers, für bestehende Integrationen beibehalten. Neuer Code sollte error lesen.

Jeder Code hat eine eigene Seite unter Fehlercodes mit seinem HTTP-Status, den Feldern von details und den Endpunkten, die ihn zurückgeben. Die Seite jedes Endpunkts in der API-Referenz listet die Codes auf, die dieser Endpunkt zurückgeben kann.

HTTP-Status

StatusBedeutung
200, 201, 202, 204Die Anfrage war erfolgreich. 202 bedeutet, dass sie angenommen wurde und noch verarbeitet wird.
400Die Anfrage ist fehlerhaft: ein ungültiger Parameter, Cursor, metadata oder Idempotency-Key. Korrigieren Sie die Anfrage.
401Kein gültiger Schlüssel. Siehe Authentifizierung.
402Ein Limit des Tarifs der Organisation ist erreicht, etwa die Anzahl der Karten oder der Speicherplatz.
403Der Schlüssel ist gültig, darf dies aber nicht: Es fehlt eine Rolle, ein Scope oder eine Funktion des Tarifs.
404Das Objekt existiert nicht, oder der Schlüssel darf es nicht sehen.
409Die Anfrage steht im Konflikt mit dem aktuellen Zustand: eine doppelte external_id, eine offene Synchronisierung, eine noch laufende Anfrage mit demselben Idempotency-Key.
410Das Objekt ist abgelaufen, etwa ein Upload nach 24 Stunden, oder die Route wurde stillgelegt.
413Der Body oder die Datei ist zu groß.
415Der Dateityp wird nicht unterstützt, oder der Inhalt passt nicht zum Dateinamen.
422Die Anfrage ist formal korrekt, aber ungültig: ein fehlendes Feld oder ein Wert außerhalb des zulässigen Bereichs.
429Zu viele Anfragen, oder ein Kontingent ist aufgebraucht. Siehe Ratenlimits und Kontingente.
500, 502, 503, 504Ein Problem auf der Seite von Sursa. Versuchen Sie es später erneut.

Validierungsfehler

Bei 422 mit dem Code validation.failed listet detail jedes fehlerhafte Feld mit seiner Position auf:

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

Welche Fehler Sie wiederholen sollten

FehlerWiederholen?
Netzwerkfehler oder Timeout, keine AntwortJa, mit demselben Idempotency-Key.
429Ja, nach der Anzahl Sekunden in Retry-After.
500, 502, 503, 504Ja, mit exponentiellem Backoff: 1 s, 2 s, 4 s … bis zu einer Minute, mit zufälligem Jitter.
409 api.idempotency_in_progressJa, nach Retry-After: Die erste Anfrage mit diesem Schlüssel läuft noch.
Jeder andere 4xxNein. Dieselbe Anfrage schlägt erneut fehl; korrigieren Sie sie zuerst.

Wiederholen Sie POST- und PATCH-Anfragen nur mit einem Idempotency-Key, damit eine Wiederholung nach einer verlorenen Antwort kein zweites Objekt erzeugen kann. GET, PUT und DELETE können Sie unverändert wiederholen.

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

Ein Problem melden

Jede Antwort, ob erfolgreich oder nicht, hat einen Header X-Request-Id, und jeder Fehler hat denselben Wert in error.request_id. Protokollieren Sie ihn zusammen mit Ihrem eigenen Eintrag zur Anfrage. Wenn Sie sich wegen einer Anfrage an den Support wenden, senden Sie ihre Request-ID mit: Die ID führt direkt zum Eintrag dieser Anfrage.

Unbekannte Codes behandeln

Neue Fehlercodes können in jeder Version der API hinzukommen. Behandeln Sie einen unbekannten Code nach seinem HTTP-Status: einen unbekannten 4xx als Anfrage, die in dieser Form nicht gelingen wird, einen unbekannten 5xx als vorübergehendes Problem.