Add SOAP fault override.
authorScott Cantor <cantor.2@osu.edu>
Fri, 24 Nov 2006 22:31:39 +0000 (22:31 +0000)
committerScott Cantor <cantor.2@osu.edu>
Fri, 24 Nov 2006 22:31:39 +0000 (22:31 +0000)
xmltooling/soap/SOAPClient.h
xmltooling/soap/impl/SOAPClient.cpp

index b19b7d4..c1fc633 100644 (file)
@@ -29,6 +29,7 @@
 namespace soap11 {
 
     class XMLTOOL_API Envelope;
+    class XMLTOOL_API Fault;
 
     /**
      * Implements SOAP 1.1 messaging over a transport.
@@ -73,8 +74,6 @@ namespace soap11 {
          * 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();
         
@@ -90,7 +89,15 @@ namespace soap11 {
          * @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;
 
index 01583a3..dc2f6d1 100644 (file)
 #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()
@@ -85,7 +88,29 @@ Envelope* SOAPClient::receive()
     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;
+}