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"
}
}
| Feld | Bedeutung |
|---|---|
error.code | Stabiler Code in der Form <area>.<reason>. Verzweigen Sie Ihren Code danach. |
error.message | Eine lesbare Erklärung auf Englisch. Der Text kann jederzeit umformuliert werden; werten Sie ihn nicht aus. |
error.details | Strukturierte 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_id | Die ID dieser Anfrage, dieselbe wie im Antwort-Header X-Request-Id. |
error.doc_url | Die Seite zu diesem Code in diesem Portal. |
detail | Die 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
| Status | Bedeutung |
|---|---|
200, 201, 202, 204 | Die Anfrage war erfolgreich. 202 bedeutet, dass sie angenommen wurde und noch verarbeitet wird. |
400 | Die Anfrage ist fehlerhaft: ein ungültiger Parameter, Cursor, metadata oder Idempotency-Key. Korrigieren Sie die Anfrage. |
401 | Kein gültiger Schlüssel. Siehe Authentifizierung. |
402 | Ein Limit des Tarifs der Organisation ist erreicht, etwa die Anzahl der Karten oder der Speicherplatz. |
403 | Der Schlüssel ist gültig, darf dies aber nicht: Es fehlt eine Rolle, ein Scope oder eine Funktion des Tarifs. |
404 | Das Objekt existiert nicht, oder der Schlüssel darf es nicht sehen. |
409 | Die Anfrage steht im Konflikt mit dem aktuellen Zustand: eine doppelte external_id, eine offene Synchronisierung, eine noch laufende Anfrage mit demselben Idempotency-Key. |
410 | Das Objekt ist abgelaufen, etwa ein Upload nach 24 Stunden, oder die Route wurde stillgelegt. |
413 | Der Body oder die Datei ist zu groß. |
415 | Der Dateityp wird nicht unterstützt, oder der Inhalt passt nicht zum Dateinamen. |
422 | Die Anfrage ist formal korrekt, aber ungültig: ein fehlendes Feld oder ein Wert außerhalb des zulässigen Bereichs. |
429 | Zu viele Anfragen, oder ein Kontingent ist aufgebraucht. Siehe Ratenlimits und Kontingente. |
500, 502, 503, 504 | Ein 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
| Fehler | Wiederholen? |
|---|---|
| Netzwerkfehler oder Timeout, keine Antwort | Ja, mit demselben Idempotency-Key. |
429 | Ja, nach der Anzahl Sekunden in Retry-After. |
500, 502, 503, 504 | Ja, mit exponentiellem Backoff: 1 s, 2 s, 4 s … bis zu einer Minute, mit zufälligem Jitter. |
409 api.idempotency_in_progress | Ja, nach Retry-After: Die erste Anfrage mit diesem Schlüssel läuft noch. |
Jeder andere 4xx | Nein. 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.