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 |