You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-user@axis.apache.org by Dimuthu Gamage <di...@gmail.com> on 2008/08/05 16:59:36 UTC

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 <jq...@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
>
>