- Chapter 3: Simple Object Access Protocol (SOAP)
- Simple Object Access Protocol (SOAP)
- Doing Business with SkatesTown
- Inventory Check Web Service
- SOAP Envelope Framework
- Taking Advantage of SOAP Extensibility
- SOAP Intermediaries
- Error Handling in SOAP
- SOAP Data Encoding
- Architecting Distributed Systems with Web Services
- Purchase Order Submission Web Service
- SOAP Protocol Bindings
- Summary
- The Road Ahead
- Resources
Error Handling in SOAP
So far in our examples everything has gone according to plan. Murphy's Law guarantees that this is not how things work out in the real world. What would happen, for example, if partner A failed to authenticate with the partner gateway application? How will this exceptional condition be communicated via SOAP? The answer lies in the semantics of the SOAP Fault element.
Consider the following possible reply message caused by the authentication failure:
HTTP/1.0 500 Internal Server Error Content-Type: text/xml; charset="utf-8" Content-Length: nnnn <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <SOAP-ENV:Fault> <faultcode>SOAP-ENV:Client.AuthenticationFailure</faultcode> <faultstring>Failed to authenticate client</faultstring> <faultactor>urn:X-SkatesTown:PartnerGateway</faultactor> </SOAP-ENV:Fault> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
Before we look at the XML, note that the HTTP response code is 500 Internal Server Error. This is a required response in the case of any SOAP-related error by the HTTP transport binding as presented in the SOAP specification. Other protocols will have their own way to report errors. The HTTP SOAP binding is discussed in detail in the section "SOAP Protocol Bindings."
The body of the response contains a single Fault element in the SOAP envelope namespace. SOAP uses this mechanism to indicate that an error has occurred and to provide some diagnostic information. There are three child elements.
The faultcode element must be present in all cases. It provides information that can be used to identify the specific error that occurred. It is not meant for human consumption. The content of the element is a string prefixed by one of the four faultcode values specified by SOAP:
VersionMismatch indicates that the namespace of the Envelope element is invalid.
MustUnderstand indicates that a required header entry was not understood.
Client indicates that likely cause of the error lies in the content or formatting of the SOAP message. In other words, the client should probably not re-send the message without making some changes to it.
Server indicates that the message failed due to reasons other than its content or its format. This leaves the door open for the same message to perhaps succeed at a later time.
A hierarchical namespace of values can be obtained by separating fault values with the dot (.) character. In our example, Client.AuthenticationFailure is a more specific fault code than Client.
The faultstring element contains a human-readable message identifying the cause of the fault. It must always be present. Here we simply state that the client has failed to authenticate.
The faultactor element provides information about where in the message path the fault occurred. It must be present if the failure occurred somewhere other than at the final destination of the SOAP message. The content of the element is the URI of the actor where the error occurred. In our example, we identify the partner gateway application as the failure point.
What is not shown in this example is how application-specific error diagnostic information can be exchanged. SOAP provides a simple mechanism for this, as well. If the fault occurred during the processing of the message body, an optional detail element can be added after faultactor. There are no restrictions on its contents. This rule has one important exception: If the fault occurred during the processing of a header entry, a detail element cannot be returned. Instead, the header entry should be returned with detailed error information contained therein. This is the mechanism SOAP uses to determine whether a fault was the result of header versus body processing.
SOAP Message Processing
Now that we have covered headers with mustUnderstand behavior, intermediaries, and error handling, we can completely define the rules for SOAP message processing. Upon receiving a message, a SOAP application must:
-
Determine whether it understands the version of SOAP that the message uses by inspecting the namespace value of the SOAP Envelope element. If the version is unknown, it must discard the message with a VersionMismatch error. Otherwise, it has to move to the next step.
-
Identify all parts of the message intended for the application. Typically this is done considering the application's role in the message path (intermediary or final recipient) and the values of the actor global attribute, but other information can be taken into account as well.
-
Verify that all mandatory parts of the message identified in Step 2 are supported by the application. These include mustUnderstand headers and, in the case of a final recipient, the body. If any mandatory part cannot be supported, the message is discarded with a MustUnderstand error in the case of headers and an application-specific error in the case of bodies. Otherwise, the application will move to Step 4.
-
Process all mandatory parts identified in Step 2 plus any optional parts that it knows about.
-
If the application is not the final recipient of the message, it must remove all headers that it has processed before passing the message forward along its path.
Having covered the SOAP envelope framework, intermediaries, and error handling, it is now time to move to other areas of the SOAP specification.