Generated Client-Side Code
If the WSDL defines fault messages, the generated client-side sample application includes catch blocks for each operation, with one block for each defined message element.
To better understand this connection, let’s look at how a fault gets defined in the WSDL. First, the WSDL defines one or more message elements to be used by the fault:
For instance, the following WSDL excerpt contains a message that will be used by the fault, InvalidRequest. (Note that the WSDL would also require a <types> element to define the complex type tns:InvalidRequest, but this is not shown.)
<message name="faultMethodRequest">
<part name="in1" type="xsd:int"/>
</message>
<message name="faultMethodResponse">
<part name="return" type="xsd:int"/>
</message>
<message name="InvalidRequest">
Then the message element is used in defining a fault in the portType definition:
<portType name="Fault">
<operation name="faultMethod" parameterOrder="in1">
<input message="tns:faultMethodRequest"/>
<output message="tns:faultMethodResponse"/>
<fault name="InvalidRequest" message="tns:InvalidRequest"/>
</operation>
</portType>
Finally, the portType fault definition is used in the binding to define a SOAP fault:
<binding name="Fault" type="tns:Fault">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="faultMethod">
<soap:operation soapAction="faultMethod" style="rpc"/>
<input>
<soap:body use="literal"
namespace="http://www.roguewave.com/rwsf/webservice/"/>
</input>
<output>
<soap:body use="literal"
namespace="http://www.roguewave.com/rwsf/webservice/"/>
</output>
<fault name="InvalidRequest">
<soap:fault name="InvalidRequest" use="literal"/>
</operation>
</binding>
The generated client sample application would then include the following code to catch and display the fault message. For instance, here’s the code that would handle the InvalidRequest fault:
try {
rwsf::CallInfo info;
return_ret = proxy.faultMethod(info, data);
}
catch(const InvalidRequest_message& e) {
std::cout << "Fault Code: " << e.getFaultCodeAsString()
<< std::endl;
std::cout << "Fault String: " << e.getFaultString()
<< std::endl;
int data = e.getrequestInfo().getData();
std::cout << "data = " << data << std::endl;
// Use the string message data in whatever way you need...
}
// Catch blocks for other WSDL-defined message types.
// ...
// In the proxy implementation, these blocks catch
// other general exceptions
catch (const rwsf::Exception& x) {
std::cerr << "Error invoking web service: "
<< x.what() << std::endl;
} catch(std::exception& e) {
std::cerr << "Error invoking web service: "
<< e.what() << std::endl;
return 1;
} catch(...) {
std::cerr << "Unknown exception thrown" << std::endl;
}
As you can see, the generated code does not attempt to guess how the detail entry of the SOAP message needs to be handled. This entry can be anything from a simple string to a complex data element, so the service developer is the person in the best position to know how it must be handled.