Slovník pojmů
Výjimka v programování
Výjimky oddělují běžný výsledek operace od situace, kterou musí řešit jiná vrstva: porušení pravidla, nedostupná služba nebo nečekaná technická chyba.
Stručná definice
Výjimka přeruší běžné vykonávání a hledá odpovídající obsluhu.
Po throw PHP ukončí zbytek aktuální cesty a prochází zásobník volání směrem k místu s odpovídajícím catch. Pokud žádné nenajde, výjimka doputuje k globálnímu handleru nebo aplikace skončí chybou. Blok finally slouží pro úklid, který má při běžném průchodu try a catch proběhnout bez ohledu na výsledek.
Vyhazovaný objekt musí implementovat Throwable. V PHP pod něj patří Exception i Error; vlastní doménová či aplikační výjimka se běžně odvozuje od Exception nebo jeho potomka. Chytání Throwable je užitečné na nejvyšší hranici aplikace pro bezpečné zalogování, nemá ale skrývat programátorské chyby uvnitř běžné logiky.
Použití
Kde výjimka popisuje skutečně výjimečný stav
Výjimka je signál pro volající vrstvu, ne náhrada za všechny větve if a každou validační zprávu formuláře.
- nepovolený přechod stavu objednávky nebo platby
- timeout či neplatná odpověď externího marketplace API
- chyba při uložení dat nebo porušení databázového omezení
- převod technické chyby na srozumitelnou aplikační chybu
- rollback transakce a bezpečné ukončení importu či workeru
Praktický příklad
Převod chyby dopravce na význam aplikace
Aplikační služba nemusí vracet neurčitý boolean false, když se nepodaří vytvořit štítek. Zachytí konkrétní technickou chybu, uchová ji jako předchozí příčinu a předá vyšší vrstvě výjimku s významem pro daný use case. HTTP controller potom rozhodne, jakou bezpečnou odpověď ukázat klientovi.
PHP
try {
$label = $carrierClient->createLabel($shipment);
} catch (CarrierTimeout $exception) {
throw new ShippingTemporarilyUnavailable(
'Dopravce nyní neodpovídá.',
previous: $exception,
);
}
Jak to funguje
Od chyby k bezpečnému výsledku pro uživatele
Vhodné místo pro zachycení závisí na tom, kdo dokáže stav opravdu smysluplně vyřešit.
- Detekce problému Doménové pravidlo nebo infrastruktura zjistí stav, v němž nelze běžně pokračovat.
- Throw Kód vyhodí konkrétní Throwable; následující řádky aktuální větve se již nespustí.
- Propagace Výjimka prochází volajícím kódem, dokud nenarazí na odpovídající catch.
- Zpracování Vrstva, která umí rozhodnout, provede rollback, retry, logování, převod nebo rethrow.
- Hranice aplikace Controller, command nebo globální handler mapuje stav na bezpečnou HTTP odpověď či výsledek úlohy.
Hlavní části a pojmy
Typ výjimky nese význam, catch určuje odpovědnost.
Přesné typy a jasné hranice bývají užitečnější než jeden obecný catch, který potlačí vše.
throw, try a catch
Throw vytvoří neobvyklou cestu vykonávání. Try vymezuje rizikovou operaci a catch zpracuje konkrétní typ, který umí řešit.
finally
Slouží k úklidu zdrojů nebo obnovení lokálního stavu. Nemá přepisovat původní problém jinou výjimkou bez velmi dobrého důvodu.
Exception, Error a Throwable
Throwable je společný kontrakt vyhazovaných objektů. Exception typicky reprezentuje chybu aplikace či knihovny, Error může vzniknout z problému v běhu jazyka.
Překlad výjimky
Infrastrukturní detail lze na hranici adaptéru převést na výjimku s významem pro aplikaci a uchovat původní příčinu jako previous.
Chybová odpověď
HTTP odpověď nebo zpráva uživateli nemá obsahovat interní cestu, hesla, SQL ani stack trace; ty patří do chráněného logu.
Vztah k ostatním nástrojům
Výjimka není totéž co validace, log ani HTTP chyba.
Každý z těchto mechanismů zpracovává jiný aspekt neúspěšné operace.
- Validační chyba
- Očekávané chybné vstupy formuláře se často vracejí jako strukturovaný výsledek; výjimka je vhodná až podle hranice a významu operace.
- HTTP stav
- Status 400, 404 nebo 503 je odpověď protokolu. Není to typ PHP výjimky, i když ji může controller podle výjimky zvolit.
- Logování
- Log zaznamenává diagnostiku. Samotné zalogování ale nevrací aplikaci do bezpečného stavu ani nenahrazuje zpracování chyby.
- Retry a idempotence
- Dočasné selhání může vést k opakování operace, ale retry potřebuje limit, pozorování a ochranu před duplicitou.
Výhody a omezení
Výjimky zpřesňují selhání, ale mohou skrýt tok programu.
Přínosy
- oddělení běžného výsledku od chybové cesty
- konkrétní typ nese význam pro volající vrstvu
- původní příčinu lze uchovat pro diagnostiku
- finally a transakce pomáhají uklidit po neúspěchu
Časté chyby
- catch Throwable uvnitř běžné logiky a tiché pokračování
- zobrazení interní zprávy či stack trace uživateli
- výjimky jako náhrada každé očekávané větve if
- ztracení původní příčiny při překladu infrastruktury
- bezhlavé retry po timeoutu bez idempotence a limitu
Kdy dává smysl
Zachytit ji tam, kde lze stav skutečně vyřešit.
Doménový objekt může vyhodit výjimku při porušení invariantu. Adaptér externí služby může technickou chybu přeložit na aplikační typ. Až vstupní bod — HTTP controller, CLI příkaz nebo worker — obvykle ví, zda uživateli vrátit odpověď, úlohu opakovat nebo ji označit za neúspěšnou.
Není vhodné obalovat každou metodu vlastním try/catch. Pokud vrstva neumí přidat rozhodnutí, úklid nebo užitečný kontext, je často lepší nechat výjimku pokračovat do místa, které to skutečně zvládne.
Na co myslet
Chyba má být bezpečná pro klienta a užitečná pro provoz.
Dobře zvládnutá výjimka zachová diagnostiku, ale neprozradí interní detaily mimo aplikaci.
- chytat co nejkonkrétnější typ, který daná vrstva skutečně umí zpracovat
- při překladu chyby zachovat previous pro diagnostiku
- provést rollback nebo uvolnění zdroje před návratem z operace
- mapovat aplikační chyby na konzistentní a bezpečné odpovědi
- testovat důležité neúspěšné scénáře i jejich vedlejší účinky
Časté otázky
Výjimky, Throwable a chybové stavy v PHP
Je výjimka totéž co HTTP chyba?
Ne. Výjimka je objekt a tok vykonávání uvnitř PHP. HTTP stavový kód je odpověď klientovi; controller může výjimku na takovou odpověď převést.
Kdy zachytit Throwable?
Typicky na nejvyšší hranici aplikace, kde je potřeba bezpečně zalogovat nečekané selhání a vrátit obecnou odpověď. Uvnitř běžné logiky je vhodnější chytat konkrétní výjimky.
Mám pro neplatný formulář vždy vyhodit výjimku?
Ne nutně. Očekávané chyby vstupu se často vracejí jako validační výsledek. Výjimka dává větší smysl při porušení pravidla, z něhož daná vrstva nemůže běžně pokračovat.
Jak souvisí výjimky s databázovou transakcí?
Pokud operace selže uprostřed transakce, obsluha výjimky musí zajistit rollback nebo použít transakční API, které jej provede. Jinak mohou zůstat data v nečekaném stavu.
Jak PHP používám v praxi
Chybové stavy navrhuji spolu s integračními a datovými hranicemi.
U API, importů a e-commerce procesů řeším vedle úspěšné cesty také chyby externích služeb, opakování, idempotenci a bezpečné logování.