|
From: Thorsten S. <tsc...@am...> - 2010-06-22 10:35:18
|
Hello all,
I have some missing SOAP-Faults with Soap:Lite 0.710.08 on Windows
Server 2003 R2 SP2 32 Bit with
ActivePerl-5.10.1.1007-MSWin32-x86-291969.msi. We have two simple
webservices provided through SOAP::Transport::HTTP::CGI with each
having it's own dispatcher CGI-script, it's own classes etc. Soap-Lite
dispatches the requests using a class instance provided with
dipsatch_with and this class instance create a new class instance with
the real webservice logic, for example accessing the database and
doing some stuff.
I recently found that under some circumstances when the logic
implementing class dies, the execution stops as expected but the error
message does not reach the client. In those circumstances Soap-Lite
seems to generate and empty response from the called function, which
is not what I need, of course. The first time I recognized this
behaviour I hunted it down to the DESTROY method of the class with the
logic which used an eval{} to catch errors from the method
disconnecting from the database. I played a little bit and it seemd
that only the existance of an eval{} with no code in it or elswhere in
DESTROY made the difference: If the eval was present and I died
somewhere in the class, Saop-Lite didn't generate a saup:Faul but an
empty response from the called method. Without the eval{} Soap-Lite
responded with a soap-Fault, as needed. I just deleted that eval{}
because I didn't need it anymore.
Now I have the problem again and hunted it down to an eval{} in the
Package DBIx::Log4perl::db. If this eval is present and my method dies
after initiating the database connection using DBIx::Log4perl,
SOAP-Lite again just generates empty method call responses. dieing
before the database initialisation and therefore don't using
DBIx::Log4perl generates a soap:Fault, as expected. Don't using
DBIx::Log4perl but normally calling DBI->connect(...) does generate a
soap:Fault even with establashing the database connection. But of
course I want to use DBIx::Log4perl. I don't think it has something to
do with DBIx::Log4perl directly because my second webservice does
establish the database connection using DBIx::Log4perl and dieing in
that webservice after connecting does produce a soap:Fault.
It seems it has something to do with the eval{} in some specific
caller depth or stuff likie that, but I'm really stuck here. Do you
have any idea under which circumstances SOAP-Lite may not be able to
recognize a die properly or can't get the error message to produce a
soap:Fault? Thanks for any hints!
One example response how it should be:
<soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>test2 at D:/Benutzer/tschoening/Eigene Dateien/Eclipse/Perl-Bibliotheken/stmodul/elrev_dotnet.pm line 5906.</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
...and how it is with eval{} in DBIx::Log4perl::db present:
<soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<elrev_SchreibeLabelResponse xsi:nil="true" xmlns="http://localhost/elrev_dotnet"/>
</soap:Body>
</soap:Envelope>
Mit freundlichen Grüßen,
Thorsten Schöning
--
Thorsten Schöning
AM-SoFT IT-Systeme - Hameln | Potsdam | Leipzig
Telefon: Potsdam: 0331-743881-0
E-Mail: tsc...@am...
Web: http://www.am-soft.de
AM-SoFT GmbH IT-Systeme, Konsumhof 1-5, 14482 Potsdam
Amtsgericht Potsdam HRB 21278 P, Geschäftsführer: Andreas Muchow
|
|
From: Thorsten S. <tsc...@am...> - 2010-06-22 15:57:57
|
Guten Tag Thorsten Schöning,
am Dienstag, 22. Juni 2010 um 12:18 schrieben Sie:
> Now I have the problem again and hunted it down to an eval{} in the
> Package DBIx::Log4perl::db.
I've tested my code again and it seems I have this problem:
http://search.cpan.org/~elliotjs/Perl-Critic-1.106/lib/Perl/Critic/Policy/ErrorHandling/RequireCheckingReturnValueOfEval.pm
I do have DESTROY which is always called and calls
DBIx::Log4perl::db::disconnect indirectly while disocnnecting from the
database. In this function eval is used successfully, which resets $@
and SOAP-Lite can't detect the former die anymore, which let the code
stop because of an error.
What I don't understand is, if I do a eval{} myself to catch the
exception and save $@ in a variable, $@ doesn't seem to be reset. If I
die directly in that eval again, no matter if I die with $@ or
something else, SOAP-Lite sends an empty response again.
Won't work:
eval
{
someClass->new()->someMethod();
} or die 'test';
[download]
Does work:
my $retVal = undef;
eval
{
someClass->new()->someMethod();
} or $retVal = SOAP::Fault->new(faultstring => $@);
die $retVal;
[download]
$retVal will have the proper message from $@ from the die in
someMethod. I would have expected that $@ is always cleared because of
DESTROY is always called in the eval above.
Mit freundlichen Grüßen,
Thorsten Schöning
--
Thorsten Schöning
AM-SoFT IT-Systeme - Hameln | Potsdam | Leipzig
Telefon: Potsdam: 0331-743881-0
E-Mail: tsc...@am...
Web: http://www.am-soft.de
AM-SoFT GmbH IT-Systeme, Konsumhof 1-5, 14482 Potsdam
Amtsgericht Potsdam HRB 21278 P, Geschäftsführer: Andreas Muchow
|
|
From: Martin K. <mar...@fe...> - 2010-06-22 18:17:39
|
Hi Thorsten,
it looks like the DESTROY method clobbers $@ - so there are two possible
solutions: Either the one you described (which is fixing symptoms), or
localizing $@ like in
sub DESTROY {
local $@;
eval {
}
}
This restores $@ after the enclosing block.
And I heard yesterday in my local perl mongers group that perl 5.13
automatically localizes $@ in DESTROY, but I fear upgrading is not an
option ;-)
What I don't read from your mails is whether your problem is already
fixed by re-throwing a SOAP::Fault - so please send again if not.
Regards,
Martin
Am Dienstag, den 22.06.2010, 14:15 +0200 schrieb Thorsten Schöning:
> Guten Tag Thorsten Schöning,
> am Dienstag, 22. Juni 2010 um 12:18 schrieben Sie:
>
> > Now I have the problem again and hunted it down to an eval{} in the
> > Package DBIx::Log4perl::db.
>
> I've tested my code again and it seems I have this problem:
>
> http://search.cpan.org/~elliotjs/Perl-Critic-1.106/lib/Perl/Critic/Policy/ErrorHandling/RequireCheckingReturnValueOfEval.pm
>
> I do have DESTROY which is always called and calls
> DBIx::Log4perl::db::disconnect indirectly while disocnnecting from the
> database. In this function eval is used successfully, which resets $@
> and SOAP-Lite can't detect the former die anymore, which let the code
> stop because of an error.
>
> What I don't understand is, if I do a eval{} myself to catch the
> exception and save $@ in a variable, $@ doesn't seem to be reset. If I
> die directly in that eval again, no matter if I die with $@ or
> something else, SOAP-Lite sends an empty response again.
>
> Won't work:
> eval
> {
> someClass->new()->someMethod();
> } or die 'test';
> [download]
>
> Does work:
> my $retVal = undef;
> eval
> {
> someClass->new()->someMethod();
> } or $retVal = SOAP::Fault->new(faultstring => $@);
> die $retVal;
> [download]
>
> $retVal will have the proper message from $@ from the die in
> someMethod. I would have expected that $@ is always cleared because of
> DESTROY is always called in the eval above.
>
> Mit freundlichen Grüßen,
>
> Thorsten Schöning
>
|
|
From: Thorsten S. <tsc...@am...> - 2010-06-23 06:32:13
|
Guten Tag Martin Kutter,
am Dienstag, 22. Juni 2010 um 20:17 schrieben Sie:
> sub DESTROY {
> local $@;
> eval {
>
> }
> }
> This restores $@ after the enclosing block.
Thanks, I will try that later and would prefer that solution, too. I
hope it works even if the eval is down in some called methods
somewhere and not directly in DESTROY itself.
> And I heard yesterday in my local perl mongers group that perl 5.13
> automatically localizes $@ in DESTROY, but I fear upgrading is not an
> option ;-)
I surely can't force to use bleeding edge perl, right.
> What I don't read from your mails is whether your problem is already
> fixed by re-throwing a SOAP::Fault - so please send again if not.
Rethrowing the SOAP::Fault with the saved $@, like in my second
example, seems to work and the client gets the fault instead of an
empty response.
Mit freundlichen Grüßen,
Thorsten Schöning
--
Thorsten Schöning
AM-SoFT IT-Systeme - Hameln | Potsdam | Leipzig
Telefon: Potsdam: 0331-743881-0
E-Mail: tsc...@am...
Web: http://www.am-soft.de
AM-SoFT GmbH IT-Systeme, Konsumhof 1-5, 14482 Potsdam
Amtsgericht Potsdam HRB 21278 P, Geschäftsführer: Andreas Muchow
|
|
From: Thorsten S. <tsc...@am...> - 2010-06-23 07:43:37
|
Guten Tag Thorsten Schöning,
am Mittwoch, 23. Juni 2010 um 08:33 schrieben Sie:
>> sub DESTROY {
>> local $@;
>> eval {
>>
>> }
>> }
>> This restores $@ after the enclosing block.
> Thanks, I will try that later and would prefer that solution, too.
I tried that and it works, meaning with local $@ I can directly die in
my eval with $@ and get the error message as soap:Fault in the client,
without local the client gets an empty response again.
I will add local $@ just to be sure but stay with my eval because I
need it anyway. The methods I call do throw die with string messages
or Exception-objects, therefore I need something to distinguish what
comes.
Mit freundlichen Grüßen,
Thorsten Schöning
--
Thorsten Schöning
AM-SoFT IT-Systeme - Hameln | Potsdam | Leipzig
Telefon: Potsdam: 0331-743881-0
E-Mail: tsc...@am...
Web: http://www.am-soft.de
AM-SoFT GmbH IT-Systeme, Konsumhof 1-5, 14482 Potsdam
Amtsgericht Potsdam HRB 21278 P, Geschäftsführer: Andreas Muchow
|