axis-c-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jay Qiu <jqi...@yahoo.com>
Subject Re: Question about receiving custom Fault object at Axis2/C client
Date Tue, 05 Aug 2008 16:32:50 GMT
Thank Dimuthu.
I am able to get the soap fault xml from the ret_node in the generated stub code.
Now I just created C++ class to include the generated stub code and parsing the soap fault
xml to throw my own exception.
I hope WSDL2C may generate C++ code instead C for exception handling. 
Basically I added call to the following method at every stub method to throw my own exception
for service side fault: ExceptionEntry.
Thanks,
 
Jay

{
    axis2_svc_client_t* svc_client = axis2_stub_get_svc_client(m_serviceClientp, _envp
);
    {
        string fault_string = 
        axutil_qname_t *qname = NULL;
        adb_ExceptionEntry* exception_entry = NULL;
        axiom_element_t* response_element = (axiom_element_t *)axiom_node_get_data_element(response_node,
_envp);
        {
            axiom_node_t *child_nodep = axiom_node_get_first_child(response_node,
_envp);
            {
                axiom_types_t type_id = axiom_node_get_node_type(child_nodep,
_envp);
                {
                    axiom_element_t* child_elementp = (axiom_element_t*)axiom_node_get_data_element(child_nodep,
_envp);
                    qname = axiom_element_get_qname(child_elementp, _envp,
child_nodep);
                    axutil_qname_get_uri(qname, _envp),
                    axutil_qname_get_prefix(qname, _envp),
                    axutil_qname_get_localpart(qname, _envp),
                    axutil_qname_to_string(qname, _envp));voidWcfClient::checkResponse(axiom_node_t
*response_node)    if( axis2_svc_client_get_last_response_has_fault(svc_client, _envp)
)"";        if( NULL != response_element )            while( ! child_nodep
)                if( type_id == AXIOM_ELEMENT )                   
string element_name = axutil_qname_get_localpart(qname, _envp);
                    {
                        fault_string = axiom_element_get_text(child_elementp,
_envp, child_nodep);
                    }
                        exception_entry = adb_ExceptionEntry_create(_envp);
                        {
                            adb_ExceptionEntry_free(exception_entry,
_envp);
                            exception_entry = NULL;
                        }
                    }
                }
                child_nodep = axiom_node_get_next_sibling(child_nodep, _envp);
            }
        }
        {                    if( element_name == "faultstring")   
                elseif( element_name == "ExceptionEntry")                   
{                        if( adb_ExceptionEntry_deserialize(exception_entry,
_envp, &child_nodep, NULL, AXIS2_FALSE ) == AXIS2_FAILURE)               
        break;        if( NULL != exception_entry )            // found
ExceptionEntry from Service            EgWcfServiceException exceptionEntry;
            exceptionEntry._stackTrace = adb_ExceptionEntry_get__stackTrace(exception_entry,
_envp);
            exceptionEntry._innerException = adb_ExceptionEntry_get__innerException(exception_entry,
_envp);
            exceptionEntry._errorCode = adb_ExceptionEntry_get__errorCode(exception_entry,
_envp);
            exceptionEntry._externalErrorCode = adb_ExceptionEntry_get__externalErrorCode(exception_entry,
_envp);
            exceptionEntry._externalErrorSource = adb_ExceptionEntry_get__externalErrorSource(exception_entry,
_envp);
        } 
        {
            EG_EXCEPTION_1(fault_string.c_str());
        }             throwexceptionEntry;elseif( fault_string.length() >
0 )        else        {
            EG_EXCEPTION_1(
        }
    }
}"Caught unknown exception in WCF service reponse");


----- Original Message ----
From: Dimuthu Gamage <dimuthuc@gmail.com>
To: Apache AXIS C User List <axis-c-user@ws.apache.org>
Sent: Tuesday, August 5, 2008 9:59:36 AM
Subject: Re: Question about receiving custom Fault object at Axis2/C client


Hi Jay,
Unfortunately still WSDL2C doesn't support custom faults. Anyway you have done the workaround
correctly. using the _deserialize function you should be able to get the adb object corresponding
to the fault detail. Did you try printing the xml corrosponding to the batch_fault_nodep,
is it have the correct xml we expecting (the node inside the fault details node?. If so what
the error log say about the failure on deseriazing. It should have some details.

Thanks
Dimuthu


On Thu, Jul 31, 2008 at 6:44 PM, Jay Qiu <jqiu97@yahoo.com> wrote:

Hello,

We are trying to build a C++ client to connect to WCF services using basicHttpBinding.

I am able to use WSDL2C to generate the C++ stub and use the stub calls to send request to
the service and get result object back.
But I am unable to get the Fault object back. It seems to me the generated stub can not handle
the Soap Fault object.
I am wondering if any one can give me some help for receiving Fault object.

My service WSDL contains the service call GetData(string) and fault class BatchService:
   <wsdl:binding name="WSHttpBinding_IBatchService" type="i0:IBatchService">
    <wsp:PolicyReference URI="#WSHttpBinding_IBatchService_policy" />
    <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="GetData">
      <soap12:operation soapAction="" style="document" />
      <wsdl:input>
        <wsp:PolicyReference URI="#WSHttpBinding_IBatchService_GetData_Input_policy"
/>
        <soap12:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <wsp:PolicyReference URI="#WSHttpBinding_IBatchService_GetData_output_policy"
/>
        <soap12:body use="literal" />
      </wsdl:output>
      <wsdl:fault name="BatchFaultFault">
        <wsp:PolicyReference URI="#WSHttpBinding_IBatchService_GetData_BatchFaultFault_Fault"
/>
        <soap12:fault use="literal" name="BatchFaultFault" namespace="" />
      </wsdl:fault>
    </wsdl:operation>
</wsdl:binding>

WSDL2C does generate the following files:
    axis2_stub_BatchService.[hc]
    adb_GetData.[hc]
    adb_BatchFault.[hc]

However the stub request function axis2_stub_op_BatchService_GetData() inside the geratated
file axis2_stub_BatchService.c does not check if there is any fault. The function has the
following lines:
            ret_node =  axis2_svc_client_send_receive_with_op_qname( svc_client,
env, op_qname, payload);
            ret_val = adb_GetDataResponse_create(env);
            if(adb_GetDataResponse_deserialize(ret_val, env, &ret_node, NULL,
AXIS2_FALSE ) == AXIS2_FAILURE)

If the soap xml is BatchFault instead of regular return object, the  adb_GetDataResponse_deserialize()
call would fail and axis2_stub_op_BatchService_GetData() call return NULL. Thus We are unable
to get the Fault information.

If I add "xml =  axiom_node_sub_tree_to_string(ret_node, env);" after the line of
    ret_node =  axis2_svc_client_send_receive_with_op_qname( svc_client, env, op_qname,
payload);

I do see the return XML as:
    <s:Fault xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
        <faultcode>s:Client</faultcode>
        <faultstring         xmlns:xml="http://www.w3.org/XML/1998/namespace"
xml:lang="en-US">
            The creator of this fault did not specify a Reason.</faultstring>
        <detail>
            <BatchFault xmlns="http://schemas.datacontract.org/2004/07/eGlue.WCF.Common"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                <ErrorCode>1</ErrorCode>
                <ErrorMessage>Batch Fault: Input value is too big. Expected
value is less than 1000</ErrorMessage>
            </BatchFault>
        </detail>
    </s:Fault>
So should the stub provide some mechnism to return the custom Fault object or throw exception
of custom Fault object?

Also I tried to modify the generated stub code to get the BatchFault object from the return
node. But I am still unable to deserialize into BatchFault object.
Both xmls for subtree of <detail> and <BatchFault> are empty and adb_BatchFault_deserialize()
call fails also. Can you please check what is wrong in my code?

The code that I added into axis2_stub_op_BatchService_GetData() function is as following:
   if(adb_GetDataResponse_deserialize(ret_val, env, &ret_node, NULL, AXIS2_FALSE )
== AXIS2_FAILURE)
    {
      if ( axis2_svc_client_get_last_response_has_fault(svc_client, env) )
      {
       axiom_element_t* data_element = axiom_node_get_data_element(ret_node, env);
       if ( data_element != NULL )
       {
        adb_BatchFault_t* fault = NULL;
        axutil_qname_t* detail_qname = NULL;
        axutil_qname_t* batch_fault_qname = NULL;
        axiom_element_t * detail_elementp = NULL;
        axiom_node_t * detail_nodep = axiom_node_create(env);
        axiom_element_t * batch_fault_elementp = NULL;
        axiom_node_t * batch_fault_nodep = axiom_node_create(env);
        detail_qname = axutil_qname_create(env, "detail", NULL, "");
        batch_fault_qname = axutil_qname_create(env, "BatchFault", NULL, "");
        
        detail_elementp = axiom_element_get_first_child_with_qname(data_element, env,
detail_qname,  ret_node, &detail_nodep);
        if ( detail_elementp != NULL )
        {
         xml =  axiom_node_sub_tree_to_string(detail_elementp, env);
         batch_fault_elementp = axiom_element_get_first_child_with_qname(detail_elementp,
env, batch_fault_qname,  ret_node, &batch_fault_nodep);
         if ( batch_fault_elementp != NULL )
         {
          xml =  axiom_node_sub_tree_to_string(batch_fault_elementp, env);
          fault = adb_BatchFault_create(env);
          if ( adb_BatchFault_deserialize(fault, env, &batch_fault_nodep, NULL,
AXIS2_FALSE ) == AXIS2_FAILURE)
          {
           printf("Got unknown exception" );
          }
          else {
           printf("BatchFault: %s\n", adb_BatchFault_get_ErrorMessage(fault, env));
          }         
        }
      }

Thank you very much for your help.

Jay




---------------------------------------------------------------------
To unsubscribe, e-mail: axis-c-user-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-c-user-help@ws.apache.org


      
Mime
View raw message