Chyby a stavové kódy
Při vývoji volání funguje. Teď píšete část, která přijde na řadu v produkci: blok catch. Chyba HTTP z API třetí strany sama o sobě mnoho neřekne: červený stavový kód a žádná jasná odpověď na jedinou otázku, na které ve tři ráno záleží — je problém v mém požadavku, klíči, plánu, nebo v jejich serverech? A kdy mám požadavek opakovat a kdy chybu zobrazit uživateli?
Lingo.dev na to odpovídá jednotnou strukturou. Každá chyba z endpointů popsaných na těchto stránkách, synchronních i asynchronních, se vrací jako stejný objekt JSON se stavovým kódem z jedné pevně dané tabulky. Platformní API na /v2 místo toho používá standardní formát podrobností o problému; viz Chyby platformního API. Stavový kód není jen označení — říká vám, co udělat: opravit požadavek, vyměnit klíč, dobít účet, počkat, nebo požadavek opakovat. Přečtěte si kód a víte, co dál. Jediná obsluha chyb řízená stavovým kódem pokryje celé API.
Na této stránce
- Struktura chyby
- Stavové kódy
- Kdy požadavek opakovat
- 402 vs. 429: dva různé limity
- Kde najdete chyby asynchronních úloh
- Chyby platformního API
Struktura chyby#
Každá odpověď mimo rozsah 2xx má stejné tělo: objekt JSON s jediným polem message, které popisuje, co se pokazilo.
{
"message": "Invalid API key"
}To je celá specifikace. Nemusíte rozbalovat žádnou obálku ani zvlášť ošetřovat formáty chyb jednotlivých endpointů. Odpověď 400 z /process/localize a odpověď 404 při vyhledávání úlohy mají stejnou strukturu; liší se jen stavový kód a text v message.
Řiďte se stavovým kódem, ne textem zprávy
Stavový kód HTTP je stabilní vodítko — podle něj větvěte obsluhu chyb. Řetězec message je určen člověku, který čte log; berte ho jako popis, ne jako strojově čitelný chybový kód, a nerozhodujte podle jeho přesného znění.
Stavové kódy#
Všechny odpovědi pokrývá sedm stavových kódů. Níže jsou seskupeny podle toho, kdo chybu řeší, protože toto rozdělení zároveň určuje pravidla pro opakování požadavků.
Odeslali jste požadavek, který nelze splnit (opravte ho, neopakujte ho naslepo):
| Stav | Význam |
|---|---|
400 Bad Request | Požadavek neprošel validací — chybí pole, jazyk je neplatný, callbackUrl používá HTTP místo HTTPS nebo mají odeslaná data nesprávnou strukturu. |
401 Unauthorized | Hlavička X-API-Key chybí nebo je neplatná. Viz Autentizace. |
403 Forbidden | Klíč je platný, ale nemá přístup k požadovanému prostředku. |
404 Not Found | Prostředek — engine, úloha nebo skupina úloh — neexistuje. |
Vaše organizace dosáhla limitu účtu (vyřešte ho ve fakturaci):
| Stav | Význam |
|---|---|
402 Payment Required | Organizace dosáhla svého kreditního limitu. |
429 Too Many Requests | Organizace dosáhla své denní kvóty tokenů. Limit zvýšíte přechodem na vyšší plán. |
Něco selhalo na naší straně (přechodná chyba — opakujte požadavek):
| Stav | Význam |
|---|---|
500 Internal Server Error | Neočekávané selhání — chyba databáze nebo volání překladu, které selhalo u všech modelů nakonfigurovaných v engine. |
401 a 403 vypadají podobně, ale označují různé problémy: 401 znamená, že se nám volajícího vůbec nepodařilo identifikovat; 403 znamená, že jsme klíč identifikovali, ale nemá povolený přístup. U 401 je třeba řešit samotný klíč (vyměnit ho nebo zkontrolovat); u 403 jeho přístupová oprávnění.
Kdy požadavek opakovat#
Při pohledu na jakoukoli tabulku chyb si skeptický vývojář při integraci nejdřív položí otázku, kterou tabulka obvykle nezodpoví: u kterých chyb mám požadavek opakovat? Odpověď dává rozdělení výše.
- 4xx — neopakujte požadavek naslepo. Kódy
400,401,403nebo404popisují problém ve vašem požadavku. Opakování totožného požadavku vyvolá totožnou chybu. Opravte vstup, klíč nebo ID prostředku a pak požadavek odešlete znovu. - 402 a 429 — počkejte a pak vyřešte limit. Na úrovni požadavku nejde o přechodné chyby; další požadavek narazí na stejnou překážku, dokud se příslušný limit nezmění. Přestaňte požadavek opakovat v rychlé smyčce, zobrazte informaci o limitu a vyřešte ho (dobitím účtu nebo přechodem na vyšší plán).
- 500 — opakujte požadavek s postupně delšími prodlevami. Toto je jediná skutečně přechodná kategorie chyb.
500může znamenat, že při daném volání vypršel časový limit všech nakonfigurovaných modelů; při opakování může požadavek zpracovat funkční model. Použijte exponenciálně rostoucí prodlevy a omezte maximální počet opakování.
Asynchronní API hlásí výsledky jinak
Tato pravidla pro opakování platí pro synchronní volání, která provádíte sami. Asynchronní lokalizační API neposkytuje stavový kód s výsledkem zpracování: POST vrátí 202, jakmile je požadavek přijat, a každý cílový jazyk se zpracovává jako samostatná úloha prostřednictvím odolných workflow na pozadí. Místo zachycení stavového kódu původního volání se pravidelně dotazujete na stav úlohy nebo výsledek obdržíte přes webhook. Viz kde najdete chyby asynchronních úloh.
402 vs. 429: dva různé limity#
Tyto dva kódy na úrovni účtu znějí podobně — oba naznačují, že vám „něco došlo“. Jejich záměna ale vede vývojáře k nesprávnému řešení. Jde o dva různé limity, z nichž každý má jiné řešení:
402 Payment Required– organizace dosáhla svého kreditního limitu. Jde o fakturační omezení. Další volání budou selhávat, dokud se nezmění fakturační stav vaší organizace.429 Too Many Requests– organizace dosáhla své denní kvóty tokenů. Jde o limit spotřeby, který se pravidelně obnovuje a můžete ho zvýšit přechodem na vyšší plán.
V obsluze chyb tyto kódy rozlišujte: 402 vyžaduje zásah člověka do fakturace, zatímco u 429 můžete počkat na obnovení kvóty nebo ji zvýšit přechodem na vyšší plán. Pokud oba kódy převedete na obecnou zprávu „problém s platbou“, nebude zřejmé, jaký krok má obsluha skutečně udělat.
Tělo odpovědi 402 vypadá jako u každé jiné chyby; že jde o kreditní limit, poznáte ze stavového kódu:
{
"message": "Organization has reached its credit limit"
}Kde najdete chyby asynchronních úloh#
Je tu důležitý rozdíl: vymezuje, kdy už obsluha stavových kódů není správným nástrojem.
Stavové kódy na této stránce se týkají přenosové vrstvy: popisují, zda API přijalo a mohlo obsloužit váš požadavek HTTP. 202 z asynchronního API znamená, že byl požadavek přijat — ne že překlad proběhl úspěšně. Asynchronní úloha může být bez problémů přijata, a přesto později selhat, když během zpracování vyprší časový limit modelu. Toto selhání se neprojeví stavovým kódem HTTP původního volání; zaznamená se u samotné úlohy.
Asynchronní selhání se tedy hlásí na třech místech a žádné z nich není v této tabulce:
- Stav jednotlivé úlohy. Pokud zpracování jazyka selže, u příslušné úlohy najdete
status: "failed"aerrorMessage. Viz stavy úloh. - Stav skupiny. Když zpracování některých jazyků uspěje a jiných selže, skupina hlásí
partial; překlady pro úspěšně zpracované jazyky se přesto doručí. Viz sledování skupiny úloh. - Doručení webhooku. Selhání se doručí jako událost
translation.faileds polemerror. Viz doručování webhooků.
Je tu ještě jeden rozdíl, který bývá matoucí: selhání nekritické fáze pipeline nezpůsobí selhání úlohy. Úloha se dokončí se stavem completed_with_warnings a místo chyby obsahuje varování u jednotlivých kroků. To je záležitost sledování běhu pipeline, nikoli chybového kódu; viz sledování běhů pipeline.
Chyby platformního API#
Platformní API na https://api.lingo.dev/v2 zpracovává chyby jinak. Vrací podrobnosti o problému podle RFC 9457 ve formátu application/problem+json:
{
"type": "https://lingo.dev/docs/api/errors/glossary-in-use",
"status": 409,
"title": "Glossary in use",
"detail": "Glossary gls_1 cannot be deleted while 2 engines apply it. Detach it from those engines first.",
"id": "gls_1",
"engineCount": 2
}typeidentifikuje problém. Odkazuje na stránku daného problému, kde najdete jeho pole a endpointy, které ho vracejí. Obsluhu chyb větvěte podletype.statusopakuje stavový kód HTTP.titleje krátké shrnutí, které je stejné pro všechny výskyty daného typu.detailpopisuje, co se tentokrát stalo a co dělat dál. Je určen člověku, proto ho zobrazte, místo abyste ho strojově analyzovali.- Další položky obsahují údaje o konkrétním výskytu, například výše uvedené
idaengineCount.detailse sestavuje pouze z nich, takže klient může ztypea těchto polí vytvořit vlastní text ve svém jazyce.
Pokud požadavek neprojde validací, odpověď vrátí 400 a pod errors uvede všechny neplatné hodnoty jako dvojice { "path", "message" }. Každý endpoint může také vrátit service-unavailable (503), kdy lze požadavek bezpečně opakovat s postupně delšími prodlevami, a internal-server-error (500).
Pro každý stavový kód platí jedno pravidlo:
| Stav | Význam |
|---|---|
401 | Volající není identifikován. |
402 | Limit plánu nebo přidělených oprávnění, který lze odstranit přechodem na vyšší plán nebo dobitím účtu. |
403 | Volající je identifikován, ale tuto akci nesmí provést. |
404 | Prostředek neexistuje nebo ho volající nevidí. |
409 | Požadavek je v rozporu s aktuálním stavem, například proto, že se prostředek stále používá. |
422 | Požadavek má správnou strukturu, ale některé pravidlo ho odmítá. |
429 | Limit, který se po určité době obnovuje. |
502 | Selhal poskytovatel, na kterém služba závisí. |
503 | Dočasné selhání na naší straně. Opakujte požadavek s postupně delšími prodlevami. |
Další kroky#
Při návrhu přehledné obsluhy chyb začněte dvěma kódy, na které při integraci narazíte nejdřív: těmi pro autentizaci. Pak se podívejte, kde asynchronní zpracování hlásí vlastní výsledek.