Feature #599
closedZbavit se die() v klientske knihovne
0%
Description
Vymyslet a implementovat, jak se zbavit volani die() v klientskych knihovnach tak, abychom odlisili "nase" chyby od chyb integrovanych modulu.
Napr. v ramci "naseho" kodu pouzivat navratove hodnoty a z "ciziho" kodu budeme chytat die()
Updated by Jan Soukal almost 12 years ago
Implementovano (jeste je treba poradne otestovat) v revizi 03080a62, v branchi warden-client-2.2
Co me trapi je nasledujici kod:
eval { $client->ssl_opts(verify_hostname => 1, SSL_use_cert => 1, SSL_verify_mode => 0x02, SSL_key_file => $ssl_key_file, SSL_cert_file => $ssl_cert_file, SSL_ca_file => $ssl_ca_file); } or return errMsg('Unknown error in c2s() when setting socket SSL options, ' . $@);
Prestoze vse probiha normalne, eval z nejakeho duvodu prepne do catch vetve, pricemz $@ je prazdne. Resim to zatim hackem takto:
eval { $client->ssl_opts(verify_hostname => 1, SSL_use_cert => 1, SSL_verify_mode => 0x02, SSL_key_file => $ssl_key_file, SSL_cert_file => $ssl_cert_file, SSL_ca_file => $ssl_ca_file); return 1; # fix of eval triggering 'or' statement } or return errMsg('Unknown error in c2s() when setting socket SSL options, ' . $@);
...ale urcite to neni optimalni. Nevite nekdo, kde je chyba?
Updated by Pavel Kácha almost 12 years ago
Mluvili jsme o tom, že to může být korektní chování, protože ssl_opts může vracet v některých případech nevhodnou hodnotu a {} selže bez i výjimky, protože jeho výstupem je 0/undef. Takže - na co jsi přišel? Co a kdy vrací?
Stejný problém může být i u ostatních evalů - jsou-li to evaly, jejichž poslední příkaz jen vytváří objekt: a = asdf->new(), a očekává se, že nevrátí undef, je všechno korektní. Pokud ale volají funkci/metodu (ssl_opts, proxy), u které může být korektní, že vrátí undef, je potřeba se k tomu postavit - buď to signalizuje chybu, pak je to ok, nebo je undef jedna z množiny korektních návratových hodnot, a pak je potřeba přidat jako poslední statement 1;.
Updated by Jan Soukal over 11 years ago
Pavel Kácha wrote:
Takže ssl_opts vrací (pro objekt, na nějž je volaná):Mluvili jsme o tom, že to může být korektní chování, protože ssl_opts může vracet v některých případech nevhodnou hodnotu a {} selže bez i výjimky, protože jeho výstupem je 0/undef. Takže - na co jsi přišel? Co a kdy vrací?
- při volání s jedním argumentem (klíčem) vrací hodnotu, resp. undef, není-li hodnota pro klíč definovaná (toto ale není náš případ)
- při volání s dvěma (a více) parametry (klíč, hodnota) vrací hodnotu pro poslední klíč z parametrů. Může tedy vrátit undef. Přesněji řečeno při tomto volání ssl_opts updatuje k jednotlivým klíčům nové hodnoty a vrací "starou" hodnotu posledního klíče, která může být undef - tim spíš, nebyl-li zatím tento prvek nastaven. Toto je, dle mého náš problém.
- při volání bez parametrů vrací hash všech klíčů
Ad 2) Toto je náš problém. Při volání ssl_opts ve WardenClientCommon.pm se nastavuje hash poprvé a původní hodnoty jsou undef. A proto je undef i hodnota, kterou ssl_opts vrací. Tedy podle všeho jde o korektní volání i výsledek, které si můžeme v evalu dovolit "začistit" vrácením jedničky.
Updated by Pavel Kácha over 11 years ago
Ok, souhlas. A co tedy všechny ostatní evaly? Nekončí také nějakou podezřelou funkcí, jejíž neužitečnou návratovou hodnotu by bylo záhodno zamaskovat?
Updated by Jan Soukal over 11 years ago
Dle mého v žádném dalším evalu nenastává podobný případ, jako u řešeného ssl_opts (výše). Proto si myslím, že není třeba odchytávat další "speciální" undefy v použitých evalech. Více níže:
WardenClientCommon.pm, line 68
eval { $client = SOAP::Transport::HTTP::Client->new(); } or return errMsg('Unknown error in c2s() when creating socket, SOAP::Transport::HTTP::Client->new(), ' . $@);
Konstruktor vrací $self, takže dle mého je zde undef hodnota známkou nečekané chyby.
WardenClientCommon.pm, line 90
eval { $soap = SOAP::Lite->uri($service)->proxy($uri); } or return errMsg('Unknown error in c2s() when serializing SOAP object, ' . $@);
uri vrací hodnotu uri, je-li volána bez parametrů. Je-li volána s parametrem, nastaví hodnotu uri dle paramteru a vrací $self. Pokud je volána s více paramtery, první parametr uloží do atributu uri, pro další parametr pak vrátí hodnotu odpovídajícího parametru. Zde by potenciálně mohlo dojít k návratu undef hodnot, které jsou v podstatě korektní (neinicializované atributy). Myslím ale, že v současné podobě nás to nemusí pálit, protože voláme uri s právě jedním atributem, takže návrat undef hodnoty bych považoval za výjimečný stav siganlizující chybu.
proxy vrací podobně, při volání bez parametrů, hodnotu atributu proxy. Při volání s paramterem nastaví _proxy a tuto hodnotu i vrátí. Undef není očekávaná hodnota.
WardenClientCommon.pm, line 93
if (!defined $data) { eval { $envelope = $soap->serializer->envelope(method => $method); } or return errMsg('Unknown error in c2s() when setting enevelope, ' . $@); } else { eval { $envelope = $soap->serializer->envelope(method => $method, $data); } or return errMsg('Unknown error in c2s() when setting envelope, ' . $@); }
V obou případech vrací $self->xmlize($encoded). Zde není undef "přípustná" hodnota.
WardenClientCommon.pm, line 106
eval { $result = $client->send_receive(envelope => $envelope, endpoint => $server_uri); } or return errMsg('Unknown error in c2s() sending SOAP data, ' . $@);
Zde se vrací ($code, $content), takže opět je undef nepřípustná hodnota značící chybu.
WardenClientCommon.pm, line 118
eval { $response = $soap->deserializer->deserialize($result); } or return errMsg('Unknown error in SOAP data deserialization. Received data: ' . $result . ', ' . $@);
Vrací rozparsovaná data. Dle mého ani zde není undef možná korektní hodnota.
WardenClientSend.pm, line 72, WardenClientReceive.pm, line 70
eval { # create SOAP data object $request_data = SOAP::Data->name( request => \SOAP::Data->value( SOAP::Data->name(REQUESTED_TYPE => $requested_type), SOAP::Data->name(LAST_ID => $last_id), SOAP::Data->name(MAX_RCV_EVENTS_LIMIT => $WardenClientConf::MAX_RCV_EVENTS_LIMIT) ) ) } or return errMsg('Unknown error when creating SOAP data object, ' . $@);
Tady se analogicky vrací $self (volání s parametrem), resp. $self->{_name} (volání bez parametru). Myslím, že ani tady není undef možná korektní hodnota.
Updated by Pavel Kácha about 11 years ago
- Status changed from New to Resolved
Podle všeho tedy hotovo a k zavření. Případné chyby snad odhalíme při testování.
Updated by Pavel Kácha about 11 years ago
- Status changed from Resolved to Closed