Převod všech chyb na výjimky

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
ales.kafka
Člen | 34
+
0
-

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
+
0
-

Možná je na githubu ještě branch, která to implementovala.
Nebo zkus tohle: https://packagist.org/…es/e2ex/e2ex

ales.kafka
Člen | 34
+
0
-

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?

jasir
Člen | 746
+
0
-

Sorry já nevím :-) jen jsem to náhodou zahlédl v nových packages… Budeš to muset zjistit sám. A o zkušenosti se můžeš podělit s ostatními tady… ;-)

ales.kafka
Člen | 34
+
0
-

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í?).