Nette\Debug – callback?
- jtousek
- Člen | 951
Zdravím,
potřeboval bych nějak docílit, abych při zachycení chyby (v produkčním módu) mohl odeslat na výstup uživateli jednoduchou hlášku o tom, že nastala chyba a bylo odesláno nějaké upozornění vývojářům – samozřejmě kompletní chybovou hlášku nezobrazovat v žádném případě. Tzn. potřeboval bych do laděnky nastavit jakýsi callback, který by tuto hlášku pro uživatele generoval. A úplně ideálně bych potřeboval odeslat vývojáři e-mailem odkaz na kompletní HTML kód který laděnka generuje a loguje (anebo to hodit rovnou do mejlu či jako přílohu).
Zatím mi to připadá, že laděnka chyby v produkčním módu prostě schová a zaloguje, ale jak říct uživateli „něco je špatně, pracujeme na tom…“?
Ještě ideálnější by bylo rozlišit vývojáře (např. podle IP) a tomu rovnou zobrazit odkaz na vygenerované html chyby (tyto html bych ukládal do zvlášní složky, kde by v .htaccess bylo deny pro všechny kromě právě toho vývojáře). Proč to HTML nehodit pro vývojáře rovnou na výstup? – Kvůli ajaxu – kompletní report by se hodil i u těchto požadavků, ale ve firebugu je to jen zjednodušené.
Btw. proč je třída Debug final? Zrovna v tomhle případě by se expand laděnky docela hodil…
- Petr Motejlek
- Člen | 293
Otázká má tak trochu dvě části, tak si dovolím odpověď rozdělit:
Přesně to, co popisuješ, Laděnka běžně dělá, když je správně nastavená ;). Do bootstrapu si před $application->run() přidej
<?php
$application->errorPresenter = 'Error';
$application->catchExceptions = Environment::isProduction();
?>
To nastaví, že když dojde k výjímce a aplikace je v produkčním režimu, tak Laděnka výjímku chytne. Tím errroPresenter se nastavuje presenter, kterému je předána obsluha v případě výskytu takové neodchycené výjímky. Kód toho presenteru nemusí být nijak složitý, stačí například něco jako
<?php
class ErrorPresenter extends Presenter {
public function renderDefault($exception) {
if ($this->isAjax()) {
$this->getAjaxDriver()->events[] = array('error', $exception->getMessage());
$this->terminate();
}
else {
if ($exception instanceof BadRequestException) {
Environment::getHttpResponse()->setCode($exception->getCode());
$this->setView('404');
}
else {
Environment::getHttpResponse()->setCode(500);
$this->setView('500');
Debug::processException($exception, Environment::isDebugging());
};
};
}
}
?>
Tehnle presenter podle typu chyby buď jen zobrazí stránku upozorňující na chybu v adrese (klasická 404) – tu není potřeba nijak logovat. Všechny ostatní chyby se logují – to dělá ten řádek Debug::processException(), a šablona, která se vykresluje, je taky trochu jiná u 404 než u ostatních. Pokud chceš posílat i maily, atd. dá se tuším pomocí třetího parametru Debug::processException nastavit e-mail, kam se má všechno o té výjímce poslat. Já si to neposílám, já si pravidelně čtu logy, ale tuším, že Laděnka dokonce i pozná, že jde o naprosto stejnou výjímku a tudíž nebude posílat e-mail tolikrát, kolikrát k ní dojde, ale jen jednou.
Pokud chceš vývojářům ukazovat chyby, není IMHO nic jednoduššího, než si do config.ini nadefinovat nové prostředí, které bude de facto totožné s tím, co máš jako produkční, ale nastavíš u něj mode.debug = true a mode.production = false. Potom si v bootstrapu ještě před nastavením ErrorPresenteru uděláš test na IP adresu aktuálně připojeného klienta a uděláš Environment::setName(jménoTohoProstředí). Laděnka bude automaticky vypisovat chyby hned v prohlížeči, nikam se nebude posílat e-mail, protože se ErrorPresenter ani ke slovu nedostane… Tohle bych ale nedoporučoval dělat, protože i IP se dá podvrhnout…
- vlki
- Člen | 218
Jen doplním těch pár nejistých míst.
Pro zasílání emailu při zachycení výjimky je potřeba uvést daný mail
jako třetí parametr
statické metody Debug::enable()
.
Email se odešle při prvním zachycení a do složky s logy vytvoří
soubor [název logu].monitor
. Další emaily nebude posílat do té
doby, než bude ten soubor odstraněn.
- jtousek
- Člen | 951
Díky všem za odpovědi. Nevěděl jsem, jak přesně se pracuje s tím ErrorPresenterem takže díky moc za názorný příklad. Nakonec jsem to vyřešil ještě trochu jinak podle svých představ – použil jsem production mód, soubor .log se mění podle data (nemusím myslet na mazání .monitor – prostě se mi případná chyba pošle jednou za den). Dále v ErrorPresenteru odešlu výstup s odkazem (jen pokud IP odpovídá mé IP) na soubor, který vygeneruje Debug::processException($e). Tyhle soubory jsou samozřejmě chráněné .htaccess (IP) a .htpasswd (autentizace). Výsledkem je, že chyba se mi přímo nezobrazí nikdy, zato se mi vždy zobrazí odkaz na podrobný report (ať už šlo o ajaxový požadavek nebo ne).
Editoval jtousek (13. 12. 2009 0:35)
- Tomik
- Nette Evangelist | 485
Parse error by měl být přirozeně odhalen už při vývoji. Neboť při testech by mělo dojít ke spuštění VŠECH zdrojových kódů – tudíž parse bude odhalen. Pouštět na produkční něco, co jsem si ani nepustil v prohlížeči (nemluvě o automatických testech, třeba PHPUnit) by se nemělo dělat. :)
- jtousek
- Člen | 951
Tomik: já to myslel trochu jinak… původní záměr byl, abych při ajaxovém požadavku, který skončil chybou získal odkaz na soubor, který laděnka vygenerovala – což se ovšem děje jen v produkčním módu. Jinak je aplikace stále ve vývoji. Prostě chci po laděnce asi něco trochu jiného, než na co je stavěná. :)
- Ondřej Mirtes
- Člen | 1536
jtousek napsal(a):
Tomik: já to myslel trochu jinak… původní záměr byl, abych při ajaxovém požadavku, který skončil chybou získal odkaz na soubor, který laděnka vygenerovala – což se ovšem děje jen v produkčním módu. Jinak je aplikace stále ve vývoji. Prostě chci po laděnce asi něco trochu jiného, než na co je stavěná. :)
Laděnka ty error logy hází do app/log a to přirozeně má být skryté před světem pomocí deny from all v .htaccess :)
Jinak AJAX se dobře ladí přes konzoli Firebugu a FirePHP, ale zase jen na development mašině, na produkčním serveru toto všechno musí být před očima návštěvníků skryté.
- Ondřej Mirtes
- Člen | 1536
Když se podíváš na záložku Síť do odezvy do podzáložky HTML, tak tam máš komplet Laděnku jako kdyby byla v okně prohlížeče :)
- Honza Kuchař
- Člen | 1662
Na prase error má laděnka taky něco: https://api.nette.org/…bug.php.html#80
Ale tomuto na výstupu se neubráníš: Parse error: syntax error, unexpected T_STRING, expecting T_FUNCTION in D:\www\00_Vyvoj\GRIFART\source\PHP\app\presenters\ZakazkyPresenter.php on line 20
I pokud nastavíš error_reporting(0); tak je to tam pořád.