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 <[EMAIL PROTECTED]>
To: Apache AXIS C User List <[email protected]>
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 <[EMAIL PROTECTED]> 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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]