Error handling in SOAPHTT...
The SOAPHTTPNC and SOAPHTTPNV routines give the invoker a choice, via an LE environment variable setting, of either handling SOAP faults himself (RETURN_ERROR=YES) or have the SOAPHTTPN routine handle the fault (RETURN_ERROR=NO, the default).
Both mechanisms have problems, as will be explained, and need to be improved.
If HANDLE_ERROR=YES, the SOAP UDF does not return a -443 error code, but wraps an "error" element around the SOAP response and returns that to the caller, as explained in
This works fine if the SOAP response from the invoked service did not begin with an XML declaration. If, however, the SOAP response did begin with an XML declaration, wrapping that response produces a non-wellformed XML document that a conforming XML parser will refuse to process.
For example, if the SOAP response is
After wrapping with an element we get
And this is not a well-formed XML document. Trying to parse it, for example with DB2's own XMLPARSE function, yields an error:
ERROR ENCOUNTERED DURING XML PARSING AT LOCATION 26 Only BOM is allowed before the XML declaration.RC=000C,RSN=3064.. SQLCODE=-20398
A simple workaround for this problem is to do a string replace on the return value from the SOAP UDF:
REPLACE(DB2XML.SOAPHTTPNV(endpoint, soapaction, request), 'which turns the XML declaration into a dummy processing instruction.
However, this workaround can only be used with SOAPHTTPNV which returns a VARCHAR. If the SOAP response documents may be large, we need to use SOAPHTTPNC that returns a CLOB, but REPLACE does not work on CLOBs.
Therefore, SOAPHTTPNC and SOAPHTTPNV must be modified to inspect the SOAP response. If it begins with an XML declaration (in UTF-8, UTF-16 or EBCDIC), optionally preceded by a BOM, then the start tag for the "error" element may not be inserted right at the beginning, but must be inserted after the end of that XML declaration.
In addition, we would ask for two further improvements to SOAPHTTPNC and SOAPHTTPNV.
First, it is a good idea to have the "error" element wrapped around the SOAP fault response. However, the only information it conveys right now is the HTTP status code. It would be very useful if that error element would also return, in the form of attributes, the HTTP header information from the SOAP response.
For example, when an HTTP 500 (Internal Server Error) is returned, we see a response similar to
We would like to see:
This is very useful for debugging since we can learn when and from where the error occurred.
Second, if the user chooses to let the SOAP UDF handle the error (RETURN=ERROR=NO), the invoker receives a -443 SQLCODE when an error occurs. However, the error message in the -443 is very generic. It would be great if the UDF did inspect the response from the server, check whether that response actually is a SOAP fault document, and if so, build a more useful error message from the (SOAP 1.1) or elements (SOAP 1.2) in the SOAP fault document. Only if the response does not seem to be a valid SOAP fault, a generic error message would be returned.
For example, with the following SOAP fault document being returned from the Web service:
Invalid start date
The SOAP UDF now returns a generic error message:
ROUTINE SOAPHTTPNV (SPECIFIC NAME SOAPHTTPNCIVO) HAS RETURNED AN ERROR SQLSTATE WITH DIAGNOSTIC TEXT Error due to no/unexpected HTTP return/conten. SQLCODE=-443
We would like to see a message similar to
ROUTINE SOAPHTTPNV (SPECIFIC NAME SOAPHTTPNCIVO) HAS RETURNED AN ERROR SQLSTATE WITH DIAGNOSTIC TEXT Invalid start date. SQLCODE=-443
Basler Versicherung AG