Der Aufruf funktioniert in der Entwicklung. Jetzt schreibst du den Teil, der in Produktion läuft – den Catch-Block. Ein HTTP-Fehler einer Drittanbieter-API ist für sich genommen schwer zu deuten: ein roter Statuscode und keine klare Antwort auf die einzige Frage, die um 3 Uhr morgens zählt – liegt es an meiner Anfrage, meinem Schlüssel, meinem Tarif oder an deren Servern? Und was davon sollte ich erneut versuchen, und was sollte ich dem Nutzer anzeigen?
Lingo.dev löst das mit einer klaren Struktur. Jeder Fehler – von jedem Endpunkt, synchron oder asynchron – kommt als dasselbe JSON-Objekt zurück, mit einem Statuscode aus einer festen Tabelle. Der Statuscode ist kein Label, sondern eine Handlungsanweisung: Er sagt dir, ob du die Anfrage korrigieren, den Schlüssel austauschen, das Konto aufladen, abbremsen oder den Aufruf erneut versuchen sollst. Lies den Code, dann kennst du den nächsten Schritt. Ein einziger Fehler-Handler, der auf den Statuscode verzweigt, deckt die gesamte API ab.
Auf dieser Seite
- Die Fehlerstruktur
- Statuscodes
- Welche Fehler du erneut versuchen solltest
- 402 vs. 429: zwei unterschiedliche Limits
- Wo Fehler asynchroner Jobs auftauchen
Die Fehlerstruktur#
Jede Nicht-2xx-Antwort hat denselben Body: ein JSON-Objekt mit genau einem Feld message, das beschreibt, was schiefgelaufen ist.
{
"message": "Invalid API key"
}Das ist bereits der gesamte Vertrag. Es gibt keinen Wrapper, den du erst auspacken musst, und kein endpunktspezifisches Fehlerformat, das du gesondert behandeln müsstest. Ein 400 von /process/localize und ein 404 bei einer Job-Abfrage liefern dieselbe Struktur zurück – nur der Statuscode und der Text in message unterscheiden sich.
Prüfe den Statuscode, nicht den Nachrichtentext
Der HTTP-Statuscode ist das stabile Signal – daran sollte sich deine Fehlerbehandlung verzweigen. Die Zeichenkette message ist für Menschen geschrieben, die ein Log lesen; behandle sie als Beschreibung, nicht als maschinenlesbaren Fehlercode, und matche nicht auf den exakten Wortlaut.
Statuscodes#
Sieben Statuscodes decken jede Antwort ab. Sie sind hier danach gruppiert, wer sie auflösen muss – denn genau daraus ergibt sich auch deine Retry-Strategie.
Du hast etwas gesendet, das die Anfrage nicht erfüllen kann (Anfrage korrigieren, nicht blind erneut versuchen):
| Status | Bedeutung |
|---|---|
400 Bad Request | Die Anfragevalidierung ist fehlgeschlagen – ein fehlendes Feld, eine ungültige Sprache, eine HTTP- (nicht HTTPS-) callbackUrl oder eine fehlerhafte Payload. |
401 Unauthorized | Der Header X-API-Key fehlt oder ist ungültig. Siehe Authentifizierung. |
403 Forbidden | Der Schlüssel ist gültig, hat aber keinen Zugriff auf die angeforderte Ressource. |
404 Not Found | Die Ressource – eine Engine, ein Job oder eine Jobgruppe – existiert nicht. |
Deine Organisation hat ein Kontolimit erreicht (über die Abrechnung lösen):
| Status | Bedeutung |
|---|---|
402 Payment Required | Die Organisation hat ihr Kreditlimit erreicht. |
429 Too Many Requests | Die Organisation hat ihr tägliches Token-Kontingent erreicht. Upgrade den Tarif, um das Limit zu erhöhen. |
Auf unserer Seite ist etwas fehlgeschlagen (vorübergehend – erneut versuchen):
| Status | Bedeutung |
|---|---|
500 Internal Server Error | Ein unerwarteter Fehler – ein Datenbankfehler oder der Übersetzungsaufruf ist über alle in der Engine konfigurierten Modelle hinweg fehlgeschlagen. |
Ein 401 und ein 403 sehen ähnlich aus, sind aber nicht dasselbe Problem: 401 bedeutet, dass wir den Aufrufer überhaupt nicht identifizieren konnten, 403 bedeutet, dass wir den Schlüssel identifiziert haben, er aber keinen Zugriff hat. Die Lösung für 401 liegt beim Schlüssel selbst (rotieren oder prüfen); die Lösung für 403 liegt bei den Zugriffsrechten des Schlüssels.
Welche Fehler du erneut versuchen solltest#
Die erste Frage eines skeptischen Integrators zu jeder Fehlertabelle ist meist genau die, die oft offenbleibt: Welche davon sollte ich erneut versuchen? Die obige Gruppierung ist die Antwort.
- 4xx – nicht blind erneut versuchen. Ein
400,401,403oder404beschreibt einen Zustand in deiner Anfrage. Wenn du dieselbe Anfrage erneut sendest, bekommst du denselben Fehler noch einmal. Korrigiere die Eingabe, den Schlüssel oder die Ressourcen-ID und sende die Anfrage dann erneut. - 402 und 429 – abbremsen und dann das Limit auflösen. Diese Fehler sind auf Anfrageebene nicht vorübergehend; die nächste Anfrage läuft in dieselbe Grenze, bis sich das zugrunde liegende Limit ändert. Hör auf, in einer engen Schleife zu retryn, mach das Limit sichtbar und löse es auf (Konto aufladen oder Tarif upgraden).
- 500 – mit Backoff erneut versuchen. Das ist die eine Klasse, die tatsächlich vorübergehend ist. Ein
500kann bedeuten, dass bei diesem Aufruf jedes konfigurierte Modell ein Timeout hatte; ein Retry kann bei einem gesunden Modell landen. Verwende exponentiellen Backoff und eine Obergrenze für Wiederholungen.
Die asynchrone API meldet Ergebnisse anders
Diese Retry-Strategie gilt für synchrone Aufrufe, die du selbst ausführst. Die asynchrone localization API gibt dir keinen Statuscode für das Ergebnis der Arbeit: Ein POST liefert 202, sobald die Anfrage akzeptiert wurde, und jede Zielsprache läuft als unabhängiger Job über dauerhafte Hintergrund-Workflows. Du pollst den Job oder erhältst einen Webhook mit dem Ergebnis, statt bei deinem ursprünglichen Aufruf einen Statuscode abzufangen. Siehe wo Fehler asynchroner Jobs auftauchen.
402 vs. 429: zwei unterschiedliche Limits#
Die beiden Codes auf Kontoebene klingen ähnlich – beide wirken wie „dir ist etwas ausgegangen“ – und wenn man sie verwechselt, landet ein Entwickler bei der falschen Lösung. Es sind unterschiedliche Limits mit unterschiedlichen Wegen zur Behebung:
402 Payment Required– die Organisation hat ihr Kreditlimit erreicht. Das ist eine Abrechnungsgrenze. Der nächste Aufruf schlägt weiter fehl, bis sich der Abrechnungsstatus deiner Organisation ändert.429 Too Many Requests– die Organisation hat ihr tägliches Token-Kontingent erreicht. Das ist eine Nutzungsgrenze, die zurückgesetzt wird, und du erhöhst sie durch ein Tarif-Upgrade.
Der Grund, sie in deinem Handler getrennt zu halten: Ein 402 erfordert eine Abrechnungsaktion durch eine Person; ein 429 ist ein Kontingent, das du entweder abwartest oder per Upgrade anhebst. Beide in eine generische Meldung wie „Zahlungsproblem“ zu werfen, verschleiert, an welchem Hebel der Verantwortliche tatsächlich ziehen muss.
Ein 402-Body sieht aus wie jeder andere Fehler – der Statuscode sagt dir, dass es um das Kreditlimit geht:
{
"message": "Organization has reached its credit limit"
}Wo Fehler asynchroner Jobs auftauchen#
Hier lohnt es sich, eine Grenze zu ziehen – denn ab diesem Punkt ist ein Statuscode-Handler nicht mehr das richtige Werkzeug.
Die Statuscodes auf dieser Seite sind auf Transportebene: Sie beschreiben, ob die API deine HTTP-Anfrage akzeptiert hat und bedienen konnte. Ein 202 von der asynchronen API bedeutet, dass deine Anfrage akzeptiert wurde – nicht, dass die Übersetzung erfolgreich war. Ein asynchroner Job kann sauber angenommen werden und trotzdem später scheitern, wenn während der Ausführung ein Modell in ein Timeout läuft. Dieser Fehler ist kein HTTP-Statuscode deines ursprünglichen Aufrufs; er wird direkt am Job erfasst.
Asynchrone Fehler tauchen also an drei Stellen auf – und keine davon ist diese Tabelle:
- Status pro Job. Eine fehlgeschlagene Sprache trägt
status: "failed"und einerrorMessageam Job. Siehe Job-Status. - Gruppenstatus. Wenn einige Sprachen erfolgreich sind und andere fehlschlagen, meldet die Gruppe
partial– die erfolgreichen Sprachen werden trotzdem ausgeliefert. Siehe eine Jobgruppe nachverfolgen. - Webhook-Zustellung. Ein Fehler wird als Ereignis
translation.failedmit einem Felderrorzugestellt. Siehe Webhook-Zustellung.
Es gibt noch eine weitere Unterscheidung, über die Menschen oft stolpern: Wenn eine nicht kritische Pipeline-Stufe fehlschlägt, scheitert der Job nicht. Der Job wird mit completed_with_warnings und Warnungen pro Schritt statt mit einem Fehler abgeschlossen. Das ist ein Thema der Pipeline-Beobachtbarkeit, kein Fehlercode – siehe Pipeline-Ausführungen beobachten.
Nächste Schritte#
Ein sauberer Fehler-Handler beginnt mit den zwei Codes, die du bei der Integration zuerst sehen wirst – Authentifizierung und den Stellen, an denen asynchrone Arbeit ihr eigenes Ergebnis meldet.
