Eine Anfrage scheitert mit GatewayRequestException
Umgebung
Jede Version des Clients gegen den Datendienst Wkl.Data.Gateway.
Ursache
Jede Fehlerquelle – Antwort des Dienstes, Zeitüberschreitung, abgebrochene Verbindung, unlesbare
Antwort – kommt als GatewayRequestException mit einem GatewayProblem an: Kind (die Art),
Message (Text des Dienstes oder des Clients), CorrelationId (die Kennung, unter der der Dienst die
Einzelheiten protokolliert) und IsTransient (true nur bei Unavailable und TimedOut).
Der Dienst nennt in seiner Antwort einen Code, und der Client übernimmt dessen Art. Fehlt der Code –
etwa weil ein Proxy oder ein Lastverteiler statt des Dienstes antwortete –, ordnet der Client nach
dem HTTP-Status ein: 400 → MalformedRequest, 401 → Unauthenticated, 403 → Forbidden,
404 → UnknownResource, 409 → Conflict, 412 → PreconditionFailed, 413, 414 und 429 →
LimitExceeded, 422 → DatabaseRejected, 504 → TimedOut, jeder andere Status → Unavailable.
Seine eigenen Fehler meldet der Dienst mit diesen Codes; ein 500 stammt aus einem Glied zwischen
Client und Dienst oder aus einem unerwarteten Fehler, den der Dienst nicht abfangen konnte.
Zwei Fehler kommen nicht als GatewayRequestException:
ArgumentExceptionbeim Erzeugen vonGatewayResource,GatewayQuery,GatewayFilteroderGatewayRoutineRequestund beiReadAsyncfür einen Argumentnamen: ein Name ist kein gültiger Bezeichner, oder ein Wert liegt außerhalb seines Bereichs (siehe Programmierschnittstelle). Es wurde keine Anfrage gesendet.JsonExceptionbeim Lesen der Zeilen: Die Antwort passt nicht zuTRow, etwa weil eine Spalte Text liefert und die Eigenschaft eine Zahl erwartet. Die Anfrage ist gelaufen; korrigieren Sie den Zeilentyp oder lesen Sie aufJsonElement.
Behebung
Kind | Bedeutung | Was tun |
|---|---|---|
Unauthenticated | kein Schlüssel gesetzt, Schlüssel ungültig, gesperrt oder abgelaufen, oder eine Anmelderegel verlangt einen zweiten Faktor | Umgebungsvariable aus ApiKeyEnvironmentVariable prüfen (sie wird je Anfrage gelesen; fehlt sie, geht keine Anfrage hinaus). Verlangt eine Regel einen zweiten Faktor, kann der Client den Schlüssel nicht nutzen; Betreuer um einen Schlüssel ohne diese Pflicht bitten |
Forbidden | die Regel des Schlüssels erlaubt den Zugriff nicht | beim Betreuer des Dienstes die Regel prüfen lassen; CorrelationId mitgeben |
UnknownResource | Alias oder Objekt gibt es nicht oder es ist nicht freigegeben – bewusst nicht unterscheidbar. Ein unbekanntes Feld kommt dagegen als MalformedRequest | Schreibweise prüfen; dann wie bei Forbidden |
UnknownResource nur bei langen Leseanfragen | ein älterer Dienst nimmt Leseanfragen im Rumpf (POST …/$query) nicht an | MaxUrlLength erhöhen oder den Dienst aktualisieren |
MalformedRequest | die Anfrage ist ungültig, etwa ein unbekanntes Feld, ein Wert eines nicht übertragbaren Typs oder Argumente für ein Objekt, das keine nimmt | Feldnamen, Filter und Werte prüfen |
LimitExceeded | zu viele Anfragen (429), Anfrage zu groß (413, 414), oder die Antwort ist größer als MaxResponseBytes und der Dienst hat ihre Länge vorab genannt | bei 429 später erneut; sonst Fenster oder Feldauswahl verkleinern bzw. MaxResponseBytes erhöhen |
DatabaseRejected | die Datenbank oder die Prozedur hat abgelehnt | Bei einer Meldung der Prozedur (THROW oder RAISERROR mit Nummer ab 50000 und Schwere 11 bis 16) steht deren Text in Message; sonst steht dort ein fester Text, und den Grund nennen EngineMessages (siehe unten) |
Conflict | die Anweisung verletzt einen Schlüssel oder eindeutigen Index, auch in einer Prozedur (ab Client 0.2.1) | nicht wiederholen: dieselbe Anfrage scheitert wieder. Werte prüfen; EngineMessages nennt die Meldung |
PreconditionFailed | der Datensatz wurde seit dem Lesen geändert (ab Client 0.2.1) | neu lesen und die Änderung auf dem neuen Stand wiederholen |
TimedOut | der Dienst hat die Anweisung nach seiner Zeitgrenze abgebrochen | Lesen: Anfrage eingrenzen oder später erneut. Aufrufen: nicht blind wiederholen – erst nachsehen, ob die Prozedur gewirkt hat |
Unavailable | Dienst oder Datenbank nicht erreichbar, Verbindung abgebrochen, Antwort unlesbar, oder der Client hat nach seiner Zeitgrenze aufgegeben | Lesen: später erneut; bleibt es, Betreuer verständigen. Aufrufen: nicht blind wiederholen – ist die Anfrage abgeschickt worden, kann die Prozedur gewirkt haben |
DatabaseUnreadable | SQL Server antwortet, kann die Datenbank des Alias aber nicht lesen (ab Client 0.2.0) | nicht wiederholen (IsTransient ist false): bleibt so, bis der Betreiber die Ursache behebt, meist durch einen Neustart von SQL Server; Betreuer mit CorrelationId verständigen |
IsTransient sagt nur, ob dieselbe Anfrage später gelingen könnte. Ob eine Wiederholung
unschädlich ist, sagt es nicht: Beim Prozeduraufruf entscheidet das die Anwendung.
Für jede Rückfrage beim Betreuer: CorrelationId, Uhrzeit, Alias und Objekt nennen.
Nicht lesbar heißt nicht jede unlesbare Datenbank. Der Dienst meldet DatabaseUnreadable nur für
eine feste Liste von Fehlernummern von SQL Server; ein Lesefehler aus einem anderen Grund kommt
weiter als Unavailable. Das Fehlen dieser Art belegt also keine lesbare Datenbank. Die Liste steht
in „HTTP: eigener Vertrag (Referenz)“ (Dokumentation des Datendienstes), Abschnitt „Fehlerform“.
Meldungen von SQL Server (ab Client 0.2.0). Problem.EngineMessages enthält je Meldung Number,
SqlState, Severity, Message und Released. Ist Released false, steht in Message ein Text
des Dienstes statt des Textes von SQL Server, weil dieser Namen von Objekten nennen würde, die der
Aufrufer nicht sehen darf, oder – unter der Anmeldung des Alias – einen Datenwert zitieren könnte;
Nummer und SQLSTATE kommen immer an. Ein Dienst vor Vertrag 0.5.0 schickt keine Meldungen; die Liste
ist dann leer. Bei einer abgebrochenen Verbindung und einer Zeitüberschreitung ist sie immer leer.