Má Nette\Web\HttpResponse vyhazovat výjimky?
- David Grudl
- Nette Core | 8227
Po půl roce s výjimkovým HttpResponse zvažuju, jestli to byl dobrý krok.
(Asi mě nebudete podezírat z nedostatečné striktnosti, celý Nette Framework je na přísnosti založen a věnovat pozornost E_NOTICE jsem doporučoval v době, kdy druhá třetina přispěvatelů do SVN byla zcela opačného mínění :-)))
Praxe ale ukazuje, že situace s výjimkami není vyvážená. Je skutečně výjimka shodící aplikaci do ErrorPresenteru adekvátní reakcí na to, že nelze odeslat hlavičku, cookie nebo nastavit HTTP kód? Co je lepší z hlediska uživatele? Co je lepší z hlediska programátora? Může programátor takovouto výjimku nějak smysluplně ošetřit?
Přemýšlím, která neodeslaná hlavička by způsobila skutečný
problém. Asi žádná. Tak „problém“ v uvozovkách. Napadá mě jen
Location: ...
, kterou však lze řešit i v HTML pomocí tagu
meta (a HttpResponse::redirect()
by to umět mohl) a Set-Cookie.
Vše ostatní se mi jeví jako podružné.
Na druhou stranu současná striktnost chování mi pomohla odhalit nějaké chybky. To striktnost obecně umí. Ale ruku na srdce, odhalené chybky byly opět spíš důsledkem výjimkového chování HttpResponse.
Jsem pro odstranění výjimek – ale jak to implementovat? Volitelně?
Další nepovinný parametr do všech metod ovlivňující chování? To
zavání chybným návrhem. Globální proměnná ovlivňující chování? To
je snad ještě horší, člověk nikdy neví, na co je nastavená a nastavoval
by ji pro jistotu neustále nebo vůbec. Nejvhodnější se mi jeví
vyhazování výjimek kompletně zrušit a přidat novou metodu
needSendHeader()
, která v případě nemožnosti odesílat
hlavičky výjimku vyhodí. V kritických místech, kde to fakt potřebuji,
bych ji zavolal před jinou metodou HttpResponse.
Zbývá pak otázka, jestli a jak mají metody na nemožnost odeslat hlavičku reagovat. Tiché řešení a úplné potlačení chyb nebo E_NOTICE nebo E_WARNING? Tiché řešení by se v praxi nejspíš ukázalo jako lákavá cesta do pekel. Všechno je krásné, dokud nenastoupíte několikahodinové pátrání po tom, proč se vám neodesílá hlavička. Mezi E_NOTICE a E_WARNING nevidím rozdíl, zvolil bych tedy to, co PHP posílá standardně.
Co si o tom myslíte?
- pmg
- Člen | 372
Obecně jsou mi výjimky sympatičtější, ale v tomto případě bude
nejspíš lepší varování, které se při vývoji přetočí ve výjimku.
Další hlavičky, u kterých by nenastavení mohlo vadit, jsou třeba
Content-type
a Content-lang
, ale pro tu první
existuje zvláštní metoda, která by mohla reagovat odlišně.
- David Grudl
- Nette Core | 8227
Jak ovšem nenastavení ošetřit? Zachytit výjimku a nic neudělat? Zobrazit error presenter? Nějak jinak?
- pmg
- Člen | 372
Nemůžu přijít na rozumný příklad, kdy by mi vadilo vyhození výjimky při neúspěšném přidání hlavičky. Na jednu stranu nemusí být na produkčním serveru nutné kvůli tomu aplikaci shazovat, na druhou stranu se pravděpodobně jedná o hrubou chybu při návrhu aplikace, která by se na produkční server neměla dostat.
Ve speciálních případech, kdy s tím počítám, mi nic nebrání
použít $httpRequest->isSent()
. Vyhazování výjimek vidím
jako přidanou hodnotu třídy HttpResponse
.
- David Grudl
- Nette Core | 8227
Nechci polemizovat nad tím, jestli to je chyba a jestli se má logovat – chyba návrhu aplikace to rozhodně je, jde o to, zda je vhodné na ni reagovat shozením do error presenteru nebo ji jen zalogovat jako E_WARNING.
Mě vychází, že je užitečnější odeslat stránku například bez nastavené expirace jakou jsem zamýšlel, než odeslat stránku chybovou.
- pmg
- Člen | 372
Nechci polemizovat nad tím, jestli to je chyba a jestli se má logovat
Jen že varování mohu teoreticky přehlédnout, a když tam žádné nebude, nemělo by být ani na serveru.
Mě vychází, že je užitečnější odeslat stránku například bez nastavené expirace jakou jsem zamýšlel, než odeslat stránku chybovou.
Co by ale udělalo poslat obrázek jako text/html
? Takže by to
možná znamenalo vyjmenovat hlavičky, u kterých to vadí.
Nejsem schopen dodat nic, co bys nevěděl, a obě řešení mají své výhody i nevýhody. Udělej, jak myslíš, za zkoušku by to stálo.
- David Grudl
- Nette Core | 8227
Zrovna u toho obrázku je situace taková, že není problém ani tak hlavička, jako spíš ten výstup, který už je odeslal.
- Petr Motejlek
- Člen | 293
Možná by stálo za to zvážit nějaký parametr $need, jako má třeba metoda getComponent(), když nenajde komponentu a $need je false, tak mi prostě vrátí null a já si to můžu otestovat a řešit; nebo si $need nastavím na true a pak to vyhazuje výjimku.
Určitě bych tam dal možnost ty výjimky umlčet, když vím, že nenastavení určité hlavičky mě nijak neomezí, naopak u těch, které jsou pro mně důležité, ať klidně aplikace spadne, když se je nepodaří odeslat.
- PetrP
- Člen | 587
m0t3jl napsal(a):
Určitě bych tam dal možnost ty výjimky umlčet, když vím, že nenastavení určité hlavičky mě nijak neomezí, naopak u těch, které jsou pro mně důležité, ať klidně aplikace spadne, když se je nepodaří odeslat.
Umlčet si jí můžu tak jako tak
try
$httpResponse->setHeader('X-Powered-By', 'Nette Framework');
catch (InvalidStateException $e)
// případně ošetření
pmg napsal(a):
Co by ale udělalo poslat obrázek jako
text/html
? Takže by to možná znamenalo vyjmenovat hlavičky, u kterých to vadí.
Když je ten obrázek volanej jako <img src="...">
tak to
většina prohlížečů zkousne.
David Grudl napsal(a):
Nechci polemizovat nad tím, jestli to je chyba a jestli se má logovat – chyba návrhu aplikace to rozhodně je, jde o to, zda je vhodné na ni reagovat shozením do error presenteru nebo ji jen zalogovat jako E_WARNING.
Během psaní téhle odpovědi jsem třikrát změnil názor jestli Exception nebo E_USER_WARNING, rozhodnutí bych nechal na poslední sobotu ;] uvidíš to jasněji po ctvrtém pivu.
- Petr Motejlek
- Člen | 293
PetrP napsal(a):
m0t3jl napsal(a):
Určitě bych tam dal možnost ty výjimky umlčet, když vím, že nenastavení určité hlavičky mě nijak neomezí, naopak u těch, které jsou pro mně důležité, ať klidně aplikace spadne, když se je nepodaří odeslat.
Umlčet si jí můžu tak jako tak
try $httpResponse->setHeader('X-Powered-By', 'Nette Framework'); catch (InvalidStateException $e) // případně ošetření
pmg napsal(a):
Co by ale udělalo poslat obrázek jako
text/html
? Takže by to možná znamenalo vyjmenovat hlavičky, u kterých to vadí.Když je ten obrázek volanej jako
<img src="...">
tak to většina prohlížečů zkousne.David Grudl napsal(a):
Nechci polemizovat nad tím, jestli to je chyba a jestli se má logovat – chyba návrhu aplikace to rozhodně je, jde o to, zda je vhodné na ni reagovat shozením do error presenteru nebo ji jen zalogovat jako E_WARNING.
Během psaní téhle odpovědi jsem třikrát změnil názor jestli Exception nebo E_USER_WARNING, rozhodnutí bych nechal na poslední sobotu ;] uvidíš to jasněji po ctvrtém pivu.
Jde o to, že když ti nevadí, že se ta hlavička nenastaví, tak vstup do catch sekce produkuje docela velkou (a hlavně v takovou chvíli zbytečnou) režiji; testování návratové hodnoty funkce na true/false je daleko rychlejší ;).
Když vím, že mi vyhození té výjimky (aka nenastavení hlavičky) bude vadit, tak klidně do toho catch blobku skočím, protože už se prostě stalo něco špatného a zpomalení pro uživatele je neodvratné :D.
- jasir
- Člen | 746
m0t3jl napsal(a):
Jde o to, že když ti nevadí, že se ta hlavička nenastaví, tak vstup do catch sekce produkuje docela velkou (a hlavně v takovou chvíli zbytečnou) režiji; testování návratové hodnoty funkce na true/false je daleko rychlejší ;).Když vím, že mi vyhození té výjimky (aka nenastavení hlavičky) bude vadit, tak klidně do toho catch blobku skočím, protože už se prostě stalo něco špatného a zpomalení pro uživatele je neodvratné :D.
Jak velkou režiji to má? Trošku to zavání premature optimalization ;-), ne? Nebo je opravdu tak významná?
- Petr Motejlek
- Člen | 293
Lhal bych, kdybych řekl, že jsem to testoval, určitě je ta režie daleko vyšší než testování na false nebo na null ;).
- David Grudl
- Nette Core | 8227
PetrP napsal(a):
Během psaní téhle odpovědi jsem třikrát změnil názor jestli Exception nebo E_USER_WARNING, rozhodnutí bych nechal na poslední sobotu ;] uvidíš to jasněji po ctvrtém pivu.
A vyřešili jsme to nějak? ;-)
- David Grudl
- Nette Core | 8227
Takže s odstupem měsíce… mám stále stejný názor, vyhazování výjimek bych zrušil.
- Vitek Jezek
- hledá kolegy | 285
posledni Posledni sobota pravi:
je tu sance, i kdyz mala, ze se neco zobrzi spatne (napr. poslu nejaky znak a pote bych mel poslat soubor). Neni ani tak problem samotne nastaveni hlavicek, ale spise fakt, ze je jiz nejde nastavit. Mame tedy za to, ze problem je u vseho jineho, nez u klasickeho HTML (napr. XML, soubory, pdfka). Jenze jak poznat, ze jde jen o html? Mozna prijde na slovo PresenterResponse.
Tedy jsme pro zachovani vyhazovani vyjimek. Pokud bychom poznali naprosto presne, ze jde o html, tak by slo udelat vyjimku
Editoval Whitek (30. 8. 2009 1:33)