Task #519
closedJednotné řešení výjimek a chyb v klientské knihovně
0%
Description
Je třeba navrhnout a implementovat jednotné řešení chyb v klientských funkcích (saveNewEvent, getNewEvents). Možností je řada (return, výjimky, exitcode). Bylo by vhodné zachovat zpětnou kompatibilitu.
Updated by Pavel Kácha over 12 years ago
- Due date set to 08/03/2012
- Assignee set to Jan Soukal
Nejprve tedy návrh.
Updated by Jan Soukal over 12 years ago
Návrh¶
Management chyb uvnitř klientské knihovny¶
Jde o správu chyb a výjimek uvnitř kódu klientské knihovny, úzce souvisí s #522 (Log/backtrace při chybě klientské knihovny)
Cizí kód¶
- Cizí kód (externí knihovny a moduly) bychom měli vždy spouštět v evalu.
Vlastní kód¶
Možnosti, jak implementovat řešení chyb v našem vlastním kódu (jádro Warden klienta):- Návratové hodnoty (returny)
- Výhody:
- V současné podobě kódu asi jednodušší implementace (co ale v budoucnu?)
- Nevýhody:
- složitější backtrace, špatná údržba
- Implementace:
- Buď umístit do evalu celý kód klienta. Z cizích knihoven chytat výjimky a u vlastního kódu sbírat return stavy (případně vylepšit backtrace pomocí confess, což už je ale vlastně odchytávání výjimek).
- Nebo v evalu volat explicitně pouze cizí kód a při výjimkách ihned převádět do return stavů. Propagovat výše pouze return stavy (jak z výjimek tak naše vlastní).
- Výhody:
- Výjimky
- Výhody:
- robustnější v případě rozsáhlejšího kódu (vyvine se Warden tímto směrem?)
- snažší backtrace
- Nevýhody:
- Vlastní třída výjimek (budeme chtít?)
- Implementace:
- Handling výjimek na úrovni evalu, v němž je zabalen celý kód klienta
- Výhody:
Po studiu materiálů a radách od kolegů mi přijde (s ohledem na budoucnost) lepší varianta vše řešit výjmkami, ale nemám s výjimkami v Perlu příliš zkušeností, takže budu rád, pokud se k tomu nějaký kovaný Perlista vyjádří
Management chyb na rozhraní mezi klientskou knihovnou a hostitelskou aplikací¶
Co (informace o chybách/stavech a do jaké míry) bude knihovna vracet a sdělovat hostující aplikaci.
Přímo se týká rozhraní funkcí getNewEvents, saveNewEvent (částečne tedy i #520 Volitelný způsob logování pro klientskou knihovnu a #504 Nenažraný stahující klient)
Současný stav¶
- Odesílající klient (saveNewEvent) vraci true/false
- Přijímající klient (getNewEvents) vrací pole nových událostí (případně prázdné pole)
Budoucnost (zpětná kompatibilita)¶
Vzhledem k rozšiřujícím se nárokům na klientské knihovny (viz výše uvedené #504, částečne #520, ale např. i #526 a další doplňky v budoucnu) přestává stávájící rozhraní stačit. Nicméně by stále měli oba klienti vracet stejné hodnoty, jako doposud, abychom docílili jakési kompatibility.
Návrh rozhraní do budoucna- Odesílající klient (hostitelská aplikace může volat):
- WardenClientSend::saveNewEvent($warden_path, \@event, \@options); kde @options bude pole obsahující provozní proměnné a do nichž bude následovat report chyb z knihovny. Pole event může obsahovat i více událostí.
- WardenClientSend::saveNewEvent($warden_path, \@event); kde \@event bude vícerozměrné pole, v němž první pole bude obsahovat zmíněné provozní proměnné (bude-li tam místo toho ihned událost, je zřejmé, že jde o klienta staré verze). Je zde možnost rozšířit i na více hlášených události v jednom běhu.
- klient stále vrací true/false
- Přijímající klient (hostitelská aplikace může volat)
- my @new_events = WardenClientReceive::getNewEvents($warden_path, $requested_type, \@options); kde options je stejne jako výše popsané
- bude-li se do budoucna uvažovat o větších změnách (a la #523 a rozsáhlejších), můžeme uvažovat o my @new_events = WardenClientReceive::getNewEvents($warden_path, \@options); kde options už bude requested_type či jeho derivát obsahovat
Těchto variant existuje jistě více, takže ponechávám k diskuzi.
Osobně bych volil v případě obou klientů druhou verzi.
Updated by Pavel Kácha over 12 years ago
- Due date changed from 08/03/2012 to 08/15/2012
Konsensus na řešení v nedohlednu, pro 2.1 tedy alespoň sjednotíme výjimky. Uprav getNewEvents tak, aby nepustil výjimky ven, ale vracel smysluplnou hodnotu - tedy aby fungovala smyčka:
while (my @events = getNewEvents(...)) { foreach my %event (@events) { # dělej něco s událostí } }
a aby současní klienti nebyli překvapení (ale to je jednoduché, pokud vrátíš undef, přiřadí se do @events nedefinované, tj. prázdné pole, a foreach zafunguje bez chyby - neudělá nic). Nerozlišujeme chybu a konec dat (při chybě se bude logovat). Měla by to celé být poměrně triviální úprava. Je potřeba také dát pozor, zda to funguje správně s #526.
Až to bude, půjde to do 2.1, ale bug nebudeme zavírat, retargetujeme na 3.0 a zařídíme se podle výsledků diskuse. V případě dotazů/nejasností se včas ptej.
Updated by Jan Soukal over 12 years ago
Do prijimajiciho klienta jsem pridal ochranu proti nerizenym chybam/vyjimkam. Kod zavren do evalu (revize 3f9dc03c), dle predchozi domluvy. Klienta lze nyni volat nasledovne (kod z ukazkoveho prijimace):
while (my @new_events = WardenClientReceive::getNewEvents($warden_path, $requested_type)) { foreach my $event_ref (@new_events) { my @event = @$event_ref; # delej neco s udalosti... } }
Zkouseli jsme i testovat vzhledem k #526 a vse se zda funkcni.
Updated by Pavel Kácha about 12 years ago
- Status changed from Resolved to Feedback
To není v pořádku. Klient teď požere výjimku a nevysype ji ani na stderr. V saveNewEvent jsi to udělal lépe.
Updated by Jan Soukal about 12 years ago
Pavel Kácha wrote:
To není v pořádku. Klient teď požere výjimku a nevysype ji ani na stderr. V saveNewEvent jsi to udělal lépe.
Opraveno v revizi ce546a18
... } # End of eval block or do { print STDERR "Warden-client unexpected end in eval block: " . $@ . "\n"; return; }; return @events; } # End of getNewEvents
Updated by Pavel Kácha about 12 years ago
- Status changed from Feedback to Resolved
Updated by Pavel Kácha about 12 years ago
- Status changed from Resolved to Closed