Převod všech chyb na výjimky
- ales.kafka
- Člen | 34
Existuje ve verzi 2.X způsob, jak všechny chyby (notice/warning/parse) v určitém bloku aplikace převést na výjimky? Dřív se něco takového plánovalo pro celé Nette, ale pokud vím, tak z toho sešlo. Nyní bych to do části aplikace potřeboval. Případně existuje nějaký workaround a jaké jsou úskalí? Nyní používám aspoň blok tryError a catchError, ale řeší to jen podmnožinu problému a není to úplně ono. Uvítám každý nápad, protože tohle zastavení aplikace při každé chybě potřebuju.
- jasir
- Člen | 746
Možná je na githubu ještě branch, která to implementovala.
Nebo zkus tohle: https://packagist.org/…es/e2ex/e2ex
- ales.kafka
- Člen | 34
jasir napsal(a):
Možná je na githubu ještě branch, která to implementovala.
Nebo zkus tohle: https://packagist.org/…es/e2ex/e2ex
Branch jsem nenašel, ale ten e2ex vypadá výborně, později vyzkouším, jestli vše funguje jak má. Jen by mě zajímalo, jestli to má nějaká omezení?
Mám kus kódu
<?php
E2EX\Converter::register(E_ALL);
try {
$command = new Command();
$result = $command->run();
} catch (Exception $e) {}
// zde zpracovani $result nebo zachyceni chyby pomoci e2ex nebo $e
?>
Tak je v $command->run()
možno používat cokoliv? Třeba
funkce z Nette, které interně využívají tryError/catchError?
- ales.kafka
- Člen | 34
Nakonec jsem se vyhnul použití jiné knihovny, protože přes běžící Nette laděnku žádná nezaregistruje shutdown callback a nemůžu tak odchytávat parser nebo fatal errory.
Konečné řešení vypadá zhruba takhle:
<?php
Nette\Diagnostics\Debugger::$onFatalError[] = function($e) {
// zalogovani chyby a vynucene ukonceni zbylych prikazu
}
set_error_handler(function($errno, $errstr, $file, $line, $context) {
if (($errno & error_reporting()) !== $errno) {
return FALSE;
}
restore_error_handler();
Nette\Diagnostics\Debugger::_exceptionHandler(new \ErrorException($errstr, $errno, 0, $file, $line));
}, E_ALL | E_STRICT);
try {
$result = $command->run();
} catch(Exception $e) {
$result = $e;
}
restore_error_handler();
?>
To volání _exceptionHandler()
je tam schválně, protože
když se v $command->run()
vyskytla notice + fatal error na
jednom řádku (např. volání funkce nad nedefinovanou proměnnou), tak jsem
to neodchytil ani v handleru, ani shutdown callbacku a skript spadnul bez
zachycení chyby (handler vyhazoval ErrorException). ::tryDebbug()
souběžně používat nejde, protože laděnka dočasně nemá pro sebe
handler. Např. starší implementace Strings::match()
končila
standardní PHP chybou. Nyní je implementován odkazovaným způsobem a vše
proběhne hladce, tj. při chybě se vyhodí výjimka. Pokud
$command->run()
vyhodí výjimku, tak ji zachytím a chovám se
k ní jako k výsledku (to jen pro kompletnost).
Kdyby někdo něco podobného řešil, tak tohle je asi nejlepší řešení. Na nic lepšího jsem nepřišel. Jen teda v produkčním režimu bych rád, kdyby vše končilo 200 (v Nette 2.0 to šlo docílit pomocí změny Content-type a znovuposlaní 200, ale nyní se implementace změnila a už to nijak nejde. Nemá někdo řešení?).