Fehlerbehandlung
Statuscodes
| Code | Wann | Wiederholen? |
|---|---|---|
200 | Erfolg | – |
201 | Ressource angelegt; Pfad im Header Location, Rumpf text/plain | – |
302 | Weiterleitung, etwa bei /api/users/me und bei öffentlichen Links | Ziel folgen |
304 | Seit If-Modified-Since unverändert — nur wenn im Backend eingeschaltet | – |
400 | Anfrage verletzt eine Regel: Rumpf, Parameter, Werttyp, Namenslänge, Filtersyntax | Nein — erst korrigieren |
401 | Nicht angemeldet oder Zugangsdaten ungültig | Erst nach neuer Anmeldung |
403 | Angemeldet, aber ohne ausreichende Rolle auf dieser Ressource | Nein |
404 | Ressource oder Route existiert nicht | Nein |
405 | Methode auf dieser Route nicht erlaubt | Nein |
500 | Unerwarteter Serverfehler | Einmal, mit Abstand |
503 | Dienst vorübergehend nicht verfügbar | Ja, mit wachsendem Abstand |
Die zwei Fehlerformate
Das Backend schreibt Fehler in zwei Formen. Welche kommt, hängt davon ab, wo der Fehler entsteht — Clients sollten beide lesen können.
Aus einer Operation (Validierung, Berechtigung, Typkonflikt):
{
"error": "constraints error",
"description": "Space name exceeds maximum of 80"
}Aus dem Ausnahme-Handler (alles, was die Operation nicht selbst abfängt):
{
"code": 400,
"type": "AGError",
"message": "The entity format is incorrect, a dictionary is expected"
}Auf code und Status verlassen, nicht auf type
type ist der Name der auslösenden Klasse im Backend. Er ist aufschlussreich beim Suchen, aber kein stabiler Vertrag. Verzweigen Sie über den HTTP-Status.
Ein robuster Leser:
async function fehlermeldung(response) {
const koerper = await response.json().catch(() => null)
return koerper?.description ?? koerper?.message ?? response.statusText
}Die Fehlerarten des Backends
Diese Ausnahmen erzeugen jeweils einen festen Statuscode:
| Fehler | Status | error im Rumpf |
|---|---|---|
AGHTTPUnauthorized | 401 | unauthorized |
AGHTTPForbidden | 403 | forbidden |
AGResourceNotFound | 404 | objectNotFound |
AGHTTPNotAllowed | 405 | method not allowed |
AGHTTPParseError | 400 | parse error |
AGHTTPConstraintsError | 400 | constraints error |
AGTypeConversionError | 400 | type conversion error |
AGHTTPValueNotFound | 400 | valueNotFound |
AGServiceUnavailable | 503 | serviceUnavailable |
401 und 403 auseinanderhalten
Die Unterscheidung ist genauer, als sie oft gehandhabt wird:
401— die Identität ist unklar. KeinAuthorization-Header, falscher Schlüssel, abgelaufenes Token.403— die Identität steht fest, ihr fehlt aber die Rolle auf dieser Ressource. Auch eine fremde Ressource, auf die Sie keinerlei Recht haben, antwortet mit403, nicht mit404.
Bei 401 kann der Header Apptive-Authorization mitkommen und sagt dann, welche Art von Anmeldung erwartet wird:
| Wert | Bedeutung |
|---|---|
link | Der öffentliche Link verlangt Benutzername und Passwort |
internal | Der Link verlangt eine angemeldete ApptiveGrid-Identität |
503 und Wiederholung
503 entsteht bei Wartungsarbeiten oder wenn eine Datenbanksperre den Zugriff kurzzeitig blockiert. Das Backend wiederholt Schreibvorgänge bei internen Sperrkonflikten bereits selbst (bis zu dreimal), bevor es aufgibt.
Für Clients heißt das: 503 ist der einzige Fehler, bei dem eine schlichte Wiederholung sinnvoll ist. Warten Sie zwischen den Versuchen zunehmend länger.
curl -s --retry 3 --retry-delay 2 --retry-all-errors \
-u "$APPTIVE_KEY:$APPTIVE_SECRET" "$BASE$GRID/entities"Schreibende Aufrufe nicht blind wiederholen
POST …/entities ist nicht idempotent: eine Wiederholung nach einer Zeitüberschreitung kann einen zweiten Eintrag anlegen. Prüfen Sie im Zweifel erst mit einem Filter, ob der Eintrag schon existiert.
Bedingtes Lesen
Bei gesetztem If-Modified-Since kann das Backend mit 304 Not Modified antworten, wenn sich die Datenbank seitdem nicht geändert hat. Der Vergleich läuft über den Änderungsstand der gesamten Datenbank, nicht über einzelne Ressourcen: ein 304 heißt „hier hat sich nichts getan", ein 200 heißt nicht zwingend, dass sich genau diese Ressource geändert hat.
304 ist optional
Ein 304 ist eine zulässige, aber keine zugesicherte Antwort. Bauen Sie Clients so, dass sie auch dann korrekt arbeiten, wenn auf eine unveränderte Datenbank ein 200 folgt.
Für gezieltes Nachführen einzelner Grids ist GET …/grids/{gridId}/updates?since=… das verlässlichere Mittel. → Grids
Zwei Fehler kommen nicht als JSON
401 und 404 aus der Routenschicht — also bevor überhaupt eine Operation läuft — antworten mit text/plain:
No handler found [404 Not Found]
unauthorized [401 Unauthorized]Ein 404 in dieser Form ist ein Hinweis darauf, dass der Pfad falsch gebaut wurde. Ein Client, der Fehlerrümpfe grundsätzlich als JSON parst, sollte hier nicht abstürzen.