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

Kind Monks,

I'm building a SOAP interface using XML::Compile::SOAP::HTTPDaemon module (version 2.02). The communication protocol is defined by WSDL files. There also exists a reference implementation of the server.

I got the HTTPDaemon running, I've loaded the WSDL definitions, and created a callback function for one of the defined operations. I'm also able to give a proper response for a proper request. WSDL definition of the operation follows:

<wsdl:operation name="sendSms"> <wsdl:input message="parlayx_sms_send:SendSms_sendSmsRequest"/> <wsdl:output message="parlayx_sms_send:SendSms_sendSmsResponse"/> <wsdl:fault name="ServiceException" message="parlayx_common_faults:S +erviceException"/> <wsdl:fault name="PolicyException" message="parlayx_common_faults:Po +licyException"/> </wsdl:operation>

The problem comes when something is wrong in the request and I want to throw an exception (return a fault response in SOAP terms). The reference server returns (e.g.) a message like this:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <soap:Fault> <faultcode>soap:Server</faultcode> <faultstring>Policy exception</faultstring> <detail> <ns3:PolicyException xmlns:ns2="http://www.csapi.org/schema/parlay +x/sms/send/v3_1/local" xmlns:ns3="http://www.csapi.org/schema/parlayx +/common/v3_1"> <messageId>POL0001</messageId> <text>A policy error occurred. Error code is POL-008: TPA is inv +alid.</text> <variables>POL-008</variables> <variables>TPA is invalid.</variables> </ns3:PolicyException> </detail> </soap:Fault> </soap:Body> </soap:Envelope>

I'm unable to get this kind of XML out of nested hash structure returned from the callback function. I tried this...:

return +{ Fault => { detail => { PolicyException => { messageId => $error_code, text => $error_message, variables => [ $error_code, $error_message, ], } }, faultcode => pack_type('SOAP-ENV', 'Server'), faultstring => 'Policy exception', }, };

...but this leads to empty detail element in the response:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/env +elope/"> <SOAP-ENV:Body> <SOAP-ENV:Fault> <faultcode>SOAP-ENV:Server</faultcode> <faultstring>Policy exception</faultstring> <detail/> </SOAP-ENV:Fault> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

I also tried to create the PolicyException element (same as in the reference response) by myself using XML::LibXML and asigning it to the 'detail' key directly, but then I get this error message:

warning: Answer included error: element `{http://www.csapi.org/schema/parlayx/common/v3_1}Polic +yException' not processed at {http://schemas.xmlsoap.org/soap/envelop +e/}Fault

Kind Monks, could please give me some good advice?

Replies are listed 'Best First'.
Re: returning Fault response in XML::Compile::SOAP::HTTPDaemon
by markov (Scribe) on Apr 28, 2010 at 10:04 UTC
    return +{ PolicyException => { faultcode => pack_type(SOAP11ENV, 'Server') , faultstring => 'policy exception' , detail => { messageId => $error_code , text => $error_message , variables => [ $error_code, $error_message, ] } } };

    See last part of the XML::Compile::SOAP::Daemon man-page.

    The fault you want to produce is addressed by its WSDL part name "PolicyException". This directly enforces the datatype you have to specify with "detail". Confusingly, that detail element is also named PolicyException. WSDL parts can be element- or type-style. This way, we can unify both styles.

Re: returning Fault response in XML::Compile::SOAP::HTTPDaemon
by buff (Acolyte) on Apr 28, 2010 at 11:27 UTC

    Mark Overmeer sent me a solution:

    return +{ PolicyException => { faultcode => pack_type(SOAP11ENV, 'Server') , faultstring => 'policy exception' , detail => { messageId => $error_code , text => $error_message , variables => [ $error_code, $error_message, ] } } };

    Thanks Mark :-)