Project

General

Profile

Actions

Feature #599

closed

Zbavit se die() v klientske knihovne

Added by Jan Soukal about 12 years ago. Updated about 11 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Jan Soukal
Category:
-
Target version:
Start date:
11/14/2012
Due date:
04/19/2013
% Done:

0%

Estimated time:

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()

Actions #1

Updated by Jan Soukal about 12 years ago

  • Tracker changed from Bug to Feature
Actions #2

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?

Actions #3

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;.

Actions #4

Updated by Jan Soukal almost 12 years ago

Pavel Kácha wrote:

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í?

Takže ssl_opts vrací (pro objekt, na nějž je volaná):
  1. 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)
  2. 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.
  3. 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.

Actions #5

Updated by Pavel Kácha almost 12 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?

Actions #6

Updated by Jan Soukal over 11 years ago

  • Due date set to 04/19/2013
Actions #7

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.

Actions #8

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í.

Actions #9

Updated by Pavel Kácha about 11 years ago

  • Status changed from Resolved to Closed
Actions

Also available in: Atom PDF