Má Nette\Web\HttpResponse vyhazovat výjimky?

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
David Grudl
Nette Core | 8082
+
0
-

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
+
0
-
try {
	$httpResponse->setHeader('X-Powered-By', 'Nette Framework');
} catch (InvalidStateException $e) {
	throw new ApplicationException('Unable to expose Nette Framework!', 0, $e);
}
pmg
Člen | 372
+
0
-

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

Jak ovšem nenastavení ošetřit? Zachytit výjimku a nic neudělat? Zobrazit error presenter? Nějak jinak?

pmg
Člen | 372
+
0
-

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

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

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

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

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

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

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

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

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

Taky jsem to netestovat, ale řekl bych, že to žádnou režii nemá ;-)

David Grudl
Nette Core | 8082
+
0
-

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? ;-)

Petr Motejlek
Člen | 293
+
0
-

No dobře, tak já vám teda budu oběma věřit ;)

David Grudl
Nette Core | 8082
+
0
-

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

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)