Vlastní exception handler do laděnky
- darthcz
- Člen | 113
Zdravím,
chtěl bych se zeptat, zda existuje nějaká možnost, jak upřesnit zpracování výjimek laděnkou.
Nechávám si výjimky probublávat do presenterů a mám tedy skoro ve všech metodách bloky zachytávání a zpracování výjimek. Jde mi o to, že na některé druhy výjimek reaguji pouze zobrazením zprávy, jiné se zprávou loguji a další nechávám probublat až do laděnky. Rád bych se těchto bloků z presenterů zbavil, když máme tu laděnku, takže se chci zeptat, jestli lze rozšířit laděnku tak, aby nereagovala na všechny výjimky v production mode error 500, ale třeba jen výpisem flashMessage.
Představoval bych si to tak, že bych zaregistroval do laděnky typ výjimky s callback funkcí, která se zavolá pro zpracování výjimky.
Díky za odpověď :)
Editoval darthcz (4. 2. 2013 8:45)
- Filip Procházka
- Moderator | 4668
To ale s laděnkou vůbec nesouvisí. Laděnka je jenom poslední záchrana, kdyby se všechno pokazilo, tak aby jsi se o tom dozvěděl. To je na tvé aplikaci aby tyhle chyby ošetřovala.
Můžeš si to ovšem ulehčit, například takto
class BasePresenter extends Nette\Application\UI\Presenter
{
public $onException = array();
/** Potřebujeme měnit chování, takže nette eventy nepoužijeme */
public function onException(\Exception $e)
{
foreach ($this->onException as $handler) {
if (callback($handler)->invoke($e, $this) === TRUE) {
return; // výjimka zpracována
}
}
// nikdo ji nechtěl :(
throw $e;
}
potom si zaregistruješ (klidně třeba v
BasePresenter::startup()
) obecné handlery
$this->onException[] = function (\Exception $e, Presenter $presenter) {
if ($e instanceof Nette\Application\AbortException) {
throw $e; // ukončení presenteru vždy vyhodit
}
};
$this->onException[] = function (\Exception $e, Presenter $presenter) {
if ($e instanceof MySpecialError) {
$presenter->flashMessage("Nastala speciální chyba");
return TRUE;
}
};
Když budeš z presenteru volat věci, které můžou skončit laděnkou, tak je hezky obalíš
try {
$this->model->operation();
} catch (\Exception $e) {
$this->onException($e);
}
Osobně tohle harakiri považuji za naprosto zbytečné. Nejlepší je psát
poctivě try {} catch () {}
. Byť můžeš podlehnout dojmu, že se
upíšeš, rozhodně se to vždy vyplatí.
- darthcz
- Člen | 113
Díky za odpověď. Chtěl jsem se zbavit právě těch try-catch bloků v presenteru, které v tvém řešení stejně musím psát, takže u toho zůstanu. Momentálně mám místo onException metodu processException, která porovnává druh instance výjimky místo callbacku.
Zdálo se mi fajn přenést odpovědnost za zpracování výjimek právě na nějaký další objekt, o který bych se nemusel starat, což mi přišlo, že laděnka hezky splňuje. Stačilo by jen přidat různá chování na různé výjimky. Je ale fakt, že pro tento účel vytvořena nebyla. A bylo by to asi trochu ,,magic", jelikož by nikdo další nevěděl, kde se ty výjimky odchytávají, pokud by nebyl nějaký standard zachytávat výjimky presenteru v nějaký speciální třídě.