17.1.17.Exposing & Processing SOAP Fault Messages

The SOAP:Fault message is used to indicate which part of SOAP request fails, so in its general form it may not have a detailed error. But in some cases it is useful to report in detail which element's input(s) are not correct.

Custom soap:fault messages can be generated by application logic as illustrated below:

Have a procedure to generate custom SOAP:Fault messages with at least one OUT parameter denoted by __SOAP_FAULT instead of __SOAP_TYPE keyword following by type to be returned as literal.

Once we have such parameter(s) declared we can set these to some value (of atomic, simple or complex type) as may be appropriate.

And finally we need to set a special connection variable 'SOAPFault', in order to signal custom SOAP:Fault on output. The value of the connection variable needs to be an array of two elements : An integer of 100, 200, 300, 400 which represents the SOAP:VersionMismatch, SOAP:MustUnderstand, SOAP:Client and SOAP:Server errors. And a string which will be printed in textual explanation, human readable format. In real life we will not need to generate 100 or 200 fault messages, but anyway it is possible to do that.

Example17.14.Signalling a custom SOAP Fault element

Consider we need to indicate to the client that some string is not a valid input, we can use the custom fault message mechanism as.

create procedure
echoStringFault (in param nvarchar,
                 out part2 nvarchar __soap_fault 'string')
returns nvarchar
{
  declare exit handler for sqlstate 'SF000'
    {
      http_request_status ('HTTP/1.1 500 Internal Server Error');
      -- we are setting the fault message
      part2 := param;
      -- and instructing the SOAP server to make error 400 with text explanation StringFault
      connection_set ('SOAPFault', vector ('400', 'StringFault'));
      ----------------^^^^^^^^^^
      return;
    };
  -- in real life signalling of the error is under some condition
  -- for example if string is longer that 10 chars
  signal ('SF000', 'echoEmptyFault');
}
;

  

And an wire dump of SOAP request

<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" ...>
  <SOAP-ENV:Body>
    <m:echoStringFault xmlns:m="http://soapinterop.org/wsdl">
      <param xsi:type="xsd:string">String</param>
    </m:echoStringFault>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
  

And SOAP Fault response

<?xml version="1.0"?>
<SOAP:Envelope SOAP:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" ...>
  <SOAP:Body>
    <SOAP:Fault>
      <faultcode>SOAP:Server</faultcode>
      <faultstring>[Virtuoso SOAP server] StringFault</faultstring>
      <detail>
        <h:part2 xmlns:h="http://soapinterop.org/wsdl" xsi:type="xsd:string">String</h:part2>
      </detail>
    </SOAP:Fault>
  </SOAP:Body>
</SOAP:Envelope>
  

Please note that in wire dumps there is no namespace declarations for brevity (places are denoted with '...').