Dan,

I've run into a lot of frustration in getting the fault handing logic to work 
in the decoupled case. Here's a summary of the main issues I've encountered, 
and some ideas for moving forward. Let me know what you think.

1. On a server-side fault, AbstractFaultChainInitiatorObserver.onMessage() 
copies the *entire* message content of the incoming message into the fault 
message. This can result in the headers of the incoming message being re-used 
on the outbound message, which breaks correlation. I don't see why any of this 
content is relevant to the outgoing message, apart from the exception that 
caused the fault. 

Proposal: just copy the content of type Exception.class.

2. On the client-side dispatch of an incoming fault, in order to jump to the 
in-fault-chain, ReadHeaderInterceptor.handleMessage() attempts to retrieve the 
Endpoint from the exchange *before* correlation occurs, i.e. when the real 
Exchange for the message is *unknown*. As a result the attempt to abort the 
current interceptor chain traversal and jump over to the in-fault-chain fails 
(as getInFaultObserver() can't be called on a non-existent Endpoint). So the 
SoapxxFaultInInterceptor is never reached and the 
message.setContent(Exception.class, ...) call never occurs. Hence the message 
is incorrectly categorized as a partial response by the ClientImpl.

Proposal: if the Endpoint is unavailable in ReadHeaderInterceptor, have the 
ReadHeaderInterceptor mark the message with a 
"deferred.fault.observer.notification" property and delay and the jump to the 
in-fault-chain until after the correlation occurs (in the WS-A layer).  

3. In lots of places in the code we determine if a message is inbound or 
outbound by comparing the current message to getExchange().getOutMessage(). 
However, this fails if the message is an *outbound fault* message, as this is 
stored in a different field on Exchange, i.e. getFaultMessage(), with no 
directional indicator. Simply checking if the current message equals 
getExchange().getOutMessage() OR getExchange.getFaultMessage() isn't 
sufficient, as this would falsely categorize an incoming fault message as 
outbound. 

Proposal: get rid of the separate FaultMessage field on Exchange, and just use 
the InMessage and OutMessage fields for both normal or fault messages. See 
point #4 for how faults may be distinguished from normal messages.  

4. The semantics of Interceptor.handleFault() are gratuitously different from 
those of JAX-WS Handler.handleFault(). As far as I can tell, no existing 
interceptor does anything useful in handleFault(), whereas the WS-A and WS-RM 
layers both incorrectly expect the handleFault() semantics to be consistent 
with the JAX-WS case. Also I don't think the JAX-WS wrapper interceptors 
actually call Handler.handleFault() appropriately (i.e. Handler.handleMessage() 
is called instead).

Proposal: when a fault occurs on the in-chain, we currently unwind the current 
chain by calling handleFault() on each previously traversed interceptor and 
then jump to the out-fault-chain, calling handleMessage() on each interceptor 
with the fault message. I'd propose changing this to drop the unwind, instead 
call faultMessage() on each interceptor in the out-fault-chain. As a result, it 
would be clear to the interceptor that:
a) a fault has occurred
b) the direction of traversal (ì.e. inbound or bound) 

Cheers,
Eoghan

PS: if replying over the weekend, please CC my gmail address.



Reply via email to