Skip to main content
HaroonTyagi
Known Participant
October 19, 2014
Question

How to handle Coldfusion SOAP Web Service Errors

  • October 19, 2014
  • 1 reply
  • 4707 views

Hi,

I have just created simple wsdl example:

My Component:

<cfcomponent displayname="mytest">

    <cffunction name="service_login_authentication" access="remote" output="true" returntype="any" hint="Returns login">
     <cfargument name="login" type="string" required="yes">
        <cfargument name="password" type="string" required="yes">

          <cfif #arguments.login# eq "abcdef" and #arguments.password# eq "123456">
                  <cfxml variable="soapRes">                
                        <kps_response>
                            <message>OK</message>
                            <token>354dfdffsdf</token>
                         </kps_response>

                    </cfxml>
             <cfelse>
                     <cfthrow type="MyException" message="INVALID LOGIN" errorcode="1000" />
         </cfif>        
 
      <cfreturn soapRes >
    </cffunction>
   
</cfcomponent>

Its generating wsdl and no problem with response but when generating any error like username and password does not match then it's generating fault code like this:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<soapenv:Body>

      <soapenv:Fault>

         <faultcode>soapenv:Server.userException</faultcode>

         <faultstring>coldfusion.xml.rpc.CFCInvocationException: [coldfusion.runtime.CustomException : INVALID LOGIN. ]</faultstring>

         <detail>

            <ns1:hostname xmlns:ns1="http://xml.apache.org/axis/">HOST_NAME</ns1:hostname>

         </detail>

      </soapenv:Fault>

   </soapenv:Body>

</soapenv:Envelope>

But I want customize Fault Code like this:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<soapenv:Body>

      <soapenv:Fault>

         <faultcode>1000</faultcode>

         <faultstring>INVALID LOGIN</faultstring>

      </soapenv:Fault>

   </soapenv:Body>

</soapenv:Envelope>

Fault Code and Fault String should be customize and I don't want detail tag completely. In old ColdFusion version like ColdFusion 8 displaying detail tag with <ns1:stackTrace xmlns:ns1="http://xml.apache.org/axis/"> coldfusion.xml.rpc.CFCInvocationException: and so on.


Any suggestions on how to create customize faultcode and faultstring is very helpful.

Thanks!!


This topic has been closed for replies.

1 reply

BKBK
Adobe Expert
October 20, 2014

A suggestion:

<cfset var isLoginValid = False>

<cftry>

    <!--- Your code for testing login --->

    <cfif arguments.login eq "abcdef" and arguments.password eq "123456">

        <cfset isLoginValid = True>

    </cfif>

    <cfif isLoginValid>

        <cfxml variable="soapRes">

           <kps_response>

               <message>OK</message>

               <token>354dfdffsdf</token>

            </kps_response>

         </cfxml>

    <cfelse>

        <cfthrow type="MyException" message="INVALID LOGIN" errorcode="1000" />

    </cfif>

<cfcatch type="MyException">

    <cfxml variable="soapRes">

        <kps_response>

        <cfoutput><faultcode>#cfcatch.errorCode#</faultcode>

        <faultstring>#cfcatch.message#</faultstring></cfoutput>

        </kps_response>

    </cfxml>

</cfcatch>

</cftry>

<cfreturn soapRes>

HaroonTyagi
Known Participant
October 21, 2014

Thanks BKBK

I have tested in this way but in this case its generating fault code inside a response like this:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

   <soapenv:Body>

     <ns1:service_soap_loginResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://DefaultNamespace">

         <service_soap_loginReturn xsi:type="ns2:Document" xmlns:ns2="http://xml.apache.org/xml-soap">

            <kps_response>

               <faultcode>1000</faultcode>

               <faultstring>Invalid</faultstring>

             <kps_response>

         </service_soap_loginReturn>

      </ns1:service_soap_loginResponse>

   </soapenv:Body>

</soapenv:Envelope>

I want that Fault code should be inside Soap:Fault like this:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

   <soapenv:Body>

      <soapenv:Fault>

         <faultcode>1000</faultcode>

         <faultstring>INVALID_PASSWORD</faultstring>

      </soapenv:Fault>

   </soapenv:Body>

</soapenv:Envelope>

Any ideas?

BKBK
Adobe Expert
December 1, 2014

It is possible I can get this fault output from GetSOAPResponse(webservice)  because I just want to pass from CFC main fault code and main response, I don't want to pass complete soap xml.


@HaroonTyagi, @Niyaz

I am now able to make time so that we can explore this question in full. First of all, let us get some assumptions and misconceptions out of the way.

For example, HaroonTyagi insisted that one should be able to throw and handle a custom exception when invoking a web service using cfhttp. This expectation may have a basis in the client-server model, where methods are explicitly invoked, but it has no basis here.

In fact, Adobe ColdFusion owes you no explanation about the use of cfhttp to invoke SOAP web services. Neither can it guarantee anything about this usage. The reason is that, using the post method of cfhttp to invoke web services is an undocumented method. By this, I mean that, although creative developers have discovered that it can be so used, it was not designed for that purpose.

The officially documented native Coldfusion ways to consume a web service are by means of <cfobject>, <cfinvoke> and createobject(), or their various script/tag equivalents. There is one big difference between these functionalities and <cfhttp method="post">. If the web service has a compulsory method, then they must call it. Neither <cfobject>, <cfinvoke> nor createobject() can intereact with a web service without explicitly calling its methods.

That is in keeping with the principles of the client-server model of computing. In this case, the web service is the server and the calling application the client. The client makes a request to the service by invoking its method; the server responds by means of a method return.

In contrast, a client using <cfhttp method="post"> may interact with a web service without calling its methods. For example, by posting a SOAP message containing a blank body to the service, as HaroonTyagi has done. In that case, you should not expect to be able to apply client-server validation methods, as these necessarily require that methods be explicitly called. In fact, in the client-server model, the method or function is the web service proper.

Therefore, you should perform custom validation in your CFC with the assumption that the service will be consumed by means of <cfobject>, <cfinvoke> or createobject(). There is a further advantage of assuming these will be used, instead of <cfhttp method="post">. The calls based on <cfobject>, <cfinvoke> and createobject() are the Coldfusion equivalents of calls that will be made from other languages, like PHP, .NET, and so on.