namespace soap11 {
class XMLTOOL_API Envelope;
+ class XMLTOOL_API Fault;
/**
* Implements SOAP 1.1 messaging over a transport.
* will be forthcoming, an exception is raised.
*
* <p>The caller is responsible for freeing the returned envelope.
- *
- * <p>Once a response is returned, the object will be reset for a subsequent call.
*/
virtual Envelope* receive();
* @param transport reference to transport layer
*/
virtual void prepareTransport(const xmltooling::SOAPTransport& transport) {}
-
+
+ /**
+ * Handling of SOAP faults.
+ *
+ * @param fault SOAP Fault received by client
+ * @return true iff the Fault should be treated as a fatal error
+ */
+ virtual bool handleFault(const soap11::Fault& fault);
+
/** Flag controlling schema validation. */
bool m_validate;
#include "exceptions.h"
#include "soap/SOAP.h"
#include "soap/SOAPClient.h"
+#include "util/NDC.h"
#include "util/XMLHelper.h"
#include "validation/ValidatorSuite.h"\r
#include <sstream>
+#include <log4cpp/Category.hh>
using namespace soap11;
using namespace xmltooling;
+using namespace log4cpp;
using namespace std;
SOAPClient::~SOAPClient()
if (!env)
throw IOException("Response was not a SOAP 1.1 Envelope.");
- reset();
+ Body* body = env->getBody();
+ if (body && body->hasChildren()) {
+ //Check for a Fault.
+ const Fault* fault = dynamic_cast<Fault*>(body->getXMLObjects().front());
+ if (fault && handleFault(*fault))
+ throw IOException("SOAP client detected a Fault.");
+ }
+
xmlObject.release();
return env;
}
+
+bool SOAPClient::handleFault(const Fault& fault)
+{
+#ifdef _DEBUG
+ xmltooling::NDC ndc("receiveSAML");
+#endif
+ QName* code = (fault.getFaultcode() ? fault.getFaultcode()->getCode() : NULL);
+ auto_ptr_char str((fault.getFaultstring() ? fault.getFaultstring()->getString() : NULL));
+ Category::getInstance(XMLTOOLING_LOGCAT".SOAPClient").error(
+ "SOAP client detected a Fault: (%s) (%s)",
+ (code ? code->toString().c_str() : "no code"),
+ (str.get() ? str.get() : "no message")
+ );
+ return true;
+}