ecuguru has asked for the wisdom of the Perl Monks concerning the following question:

Hi guys. I'm trying to error trap my Soap interface so that it can handle when the client's server goes up/down and their soap service itself goes up/down.
I'm running this as my soap call:
my $service = SOAP::Lite -> service('http://server/function.asmx?WSDL');
When the above code errors out because the client's soap interface is down, it dies with:
Service description 'http://server/function.asmx?WSDL' can't be loaded +: 404 Not Found
And it stops my loop entirely. I've got the above inside a function call, that gets called by a neverending loop. But when that error happens, the whole thing stops. I'm trying to figure out how I can trap that error, so that I can keep it from stopping the whole thing. Just getting a -1 or a function call would be nice, but haven't figured out how to set it up so that I can put in something like service || &soapGetBad();

Thanks!!

Replies are listed 'Best First'.
Re: Soap::Lite Error Handling
by PodMaster (Abbot) on Feb 24, 2006 at 09:19 UTC
    But when that error happens, the whole thing stops.
    It dies. Try
    my $service; eval { $service = SOAP::Lite -> service('http://server/function.asmx?WSDL'); } || soapGetBad(); # $@ will have the error message, perldoc -f eval

    update: fixed cut'n'paste error (extra my)

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

Re: Soap::Lite Error Handling
by ghoti (Acolyte) on Feb 24, 2006 at 14:09 UTC
    From the perldoc on SOAP::Lite you might also try on_fault.
      on_fault()
               This lets you specify a handler for "on_fault" event. The
               default behavior is to die on an transport error and to do
               nothing on other error conditions. You may change this
               behavior globally (see "DEFAULT SETTINGS") or locally,
               for a particular object.
    
    Something like this has worked for me quite well:
    # Something to store all the soap errors in - this is useful # if your code calls the soap service in a loop. # our @SOAP_ERRORS = (); .... # Get the current number of soap errors # my $error_count = scalar( @SOAP_ERRORS ); my $service = SOAP::Lite -> on_fault( \&soapGetBad ) -> service('http://server/function.asmx?WSDL'); # If the previous number of errors is the same as the current # number of errors, you know that the above service call did # not cause an error so you can process the results or whatever. # if( scalar( @SOAP_ERRORS ) == $error_count ) { ... } .... sub soapGetBad { my $soap = shift; my $res = shift; if( ref( $res ) ) { chomp( my $err = $res->faultstring ); push( @SOAP_ERRORS, "SOAP FAULT: $err" ); } else { chomp( my $err = $soap->transport->status ); push( @SOAP_ERRORS, "TRANSPORT ERROR: $err" ); } return new SOAP::SOM; }