On 11/08/2011 15:11, George wrote:
> On 11/08/2011 13:34, Waruna Ranasinghe wrote:
>> Hi Jorge,
>>
>>
>>
>> On 11 August 2011 23:04, George<[email protected]> wrote:
>>
>>> Hi all,
>>>
>>> I'm trying to capture a custom Soap Fault returned from an invoke 
>>> activity.
>>>
>>> I have successfully capture the exceptions lauched when the remote 
>>> service
>>> is unavailable by using<ext:failureHandling>. However now the problem is
>>> different.
>>>
>>> My remote service is a function like this:
>>> public void sendMyServiceException(int i) throws MyServiceException
>>>
>>> When I call it using SoapUI I get the exception soap xml code:
>>> <soapenv:Envelope 
>>> xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/
>>> ">
>>> <soapenv:Body>
>>> <soapenv:Fault>
>>> <faultcode>soapenv:Server</faultcode>
>>> <faultstring>unknown</faultstring>
>>> <detail>
>>> <ns:ServiceEmulatorMyServiceException
>>> xmlns:ns="http://serviceemulator.mydomain.com";>
>>> <MyServiceException xsi:type="ax21:MyServiceException"
>>> xmlns="http://serviceemulator.mydomain.com";
>>> xmlns:ax21="http://serviceemulator.mydomain.com/xsd";
>>> xmlns:ax23="http://io.java/xsd";
>>> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
>>> <ax21:code>1</ax21:code>
>>> <ax21:subcode>2</ax21:subcode>
>>> </MyServiceException>
>>> </ns:ServiceEmulatorMyServiceException>
>>> </detail>
>>> </soapenv:Fault>
>>> </soapenv:Body>
>>> </soapenv:Envelope>
>>>
>>>
>>> However in my BPEL process I'm not able to see it. The BPEL code for 
>>> this
>>> part is:
>>> <bpel:invoke name="InvokeException" partnerLink="ServiceEmulatorPL"
>>> operation="sendMyServiceException"
>>> portType="srvemu:ServiceEmulatorPortType"
>>> inputVariable="ServiceEmulatorPLSendMyServiceExceptionRequest"
>>> >
>>>
>> According the configuration of the above invoke activity, the operation
>> "sendMyServiceException" is a one-way (in-only) operation. Therefore the
>> BPEL process does not expect any response or even and soap fault as a
>> response.
> 
> Just I was checking that before receiving your answer ;) and it seems if 
> I set the remote method to return a value there is no problem and the 
> exception is caught.
> 
> Could you please give me some hint on how to access the values in the 
> exception an the type of exception?

I answer myown question. In the <detail> of soap fault it is the specific 
information for the exception that is wrapped in it. Therefore what we need is 
a procedure to get it.

It is done using the faultVariable and faultMessageType. This is the code for 
my example exception (see just above).

<bpel:catch faultName="srvemu:ServiceEmulatorMyServiceException"
  faultMessageType="srvemu:ServiceEmulatorMyServiceException"
  faultVariable="VariableToStoreException"
  xmlns:srvemu="http://serviceemulator.mydomain.com";>
  <bpel:sequence>
    <bpel:assign validate="no" name="AssignIteratorInCaseOfError1">
        <bpel:copy>
            <bpel:from 
xmlns:srvemuxsd="http://serviceemulator.mydomain.com/xsd";>
              
$VariableToStoreException.parameters/srvemu:MyServiceException/srvemuxsd:subcode
            </bpel:from>
            <bpel:to>
              $iterator
            </bpel:to>
        </bpel:copy>
      </bpel:assign>
  </bpel:sequence>
</bpel:catch>


The faultName is the name of the element the <detail> encloses, that is, the 
name of the exception object more ore less.

The important thing here is that is not required to declare or initialize the 
faultVariable outside enclosing it inside <variables> or similar. That means 
that this variable is only local and is valid within the catch. Besides that 
the value of the variable is directly assigned once the catch is executed (see 
BPEL 2.0 documentation for more info). It is important to note that whenever 
faultVariable is there, you have to include the type (faultMessageType) or 
element (faultElement) the variable is.

Then we can access the values from the soap exception using XPath or do 
whatever other action we want. In this case I have copy the subcode to an 
iterator variable (both are xsd:int).

Of course you can use the catchAll as displayed below, but then it is not 
possible to access the content within the exception.

Hope that helps others dealing with this stuff. There is not much documentation 
and examples out there that clarifies such issues.

Jorge
P.D.: Sorry if the explanation is not using the appropriate XML or BPEL or SOAP 
language, but this is the way I can do it ;)

 
> TA
> Jorge
> 
> 
>>
>> Thanks,
>> Waruna
>>
>>>
>>> <ext:failureHandling xmlns:ext="http://ode.apache.org/activityRecovery";>
>>> <ext:faultOnFailure>false</ext:faultOnFailure>
>>> </ext:failureHandling>
>>>
>>> <bpel:catchAll>
>>> <bpel:sequence>
>>> <!-- Assign data to variable output from invoke PingPongPLResponse -->
>>> <bpel:assign validate="no" name="AssignIteratorInCaseOfError">
>>> <bpel:copy>
>>> <bpel:from>
>>> <bpel:literal>0</bpel:literal>
>>> </bpel:from>
>>> <bpel:to>
>>> $iterator
>>> </bpel:to>
>>> </bpel:copy>
>>> </bpel:assign>
>>> </bpel:sequence>
>>> </bpel:catchAll>
>>> </bpel:invoke>
>>>
>>> I use catchAll to capture everything but I don't get any error, that is,
>>> the variable $iterator is not modified and still stores the same 
>>> value as
>>> the one assigned before. I have tried with faultOnFailure set to true 
>>> and
>>> false and no difference.
>>>
>>> When analizing the logs it seems that after ODE engine makes the call to
>>> the remote WS it directly returns without displaying anything on the log
>>> about the soap fault. When using a IN/OUT call I get both the request 
>>> and
>>> response on a correct execution displayed on the log, but in this 
>>> case only
>>> with IN and Exception, I only get the request.
>>>
>>> Any help. I would really appreaciate it.
>>>
>>> TA
>>> Jorge
>>>
>>>
>>>
>>
>>
> 
> 

Reply via email to