Steve, Yeah, with the JBI API we have to make sure that everything works fine on ServiceMix 3 with the JMS Flow (i.e. it adds some serialization constraints) as well. However, the problem you were facing was a bug in the servicemix-camel code though. The Camel API no longer has a dedicated fault message, but reuses the out message with a special flag on it. We were not taking that into account when translating from JBI -> Camel, so if there was a successful Out message as well as an exception, we were using the Out message as a Fault instead of picking the exception. Cfr. https://issues.apache.org/activemq/browse/SMXCOMP-816 for more information
I'll try adding a similar test to the NMR codebase as well to ensure we're not making the same mistake there. Thanks for reporting this issue, Gert Vanthienen ------------------------ Web: http://fusesource.com Blog: http://gertvanthienen.blogspot.com/ On Wed, Oct 20, 2010 at 6:29 PM, slew <[email protected]> wrote: > > Hi Gert, > > Just so I'm sure I understand everything...When you refer to NMR you mean > the SMX 4 NMR not the JBI NMR. I.e. it might be possible to propagate the > exceptions for both components, but the SMX4 NMR version should be > better/easier because it's not as constrained as the JBI version? > > Regarding the handleFault. I've tried with this option and what I find is, > although I can catch the fault like an exception, the underlying exception > is lost, it's just a generic FaultException, but no way to get to the > original exception unless I set it as a header property and manually handle > it. What would be great is to have camel serialize the original exception > across the JBI NMR and set it on the exchange at the other end, so that you > don't need handleFault, unless also using the convertExceptions flag. This > way it would work as seamlessly as the VM component and just allow the > endpoint URIs to be swapped over. > > The code I changed was to always put the original exception as the > MessageExchange error, it's never set on the Fault message. This change was > a bit naiive as it broke the unit tests, but it worked for my simple test > route allowing the exception to be caught in the calling route - although it > messed up the more complicated routes in the real code, so this makes me > think that there is a neat solution somewhere here. > > Thanks for helping, > Steve. > > > Gert Vanthienen wrote: >> >> L.S., >> >> Sorry, accidentally picked the wrong list to reply to :s >> >> Regards, >> >> Gert Vanthienen >> ------------------------ >> Open Source SOA: http://fusesource.com >> Blog: http://gertvanthienen.blogspot.com/ >> >> >> >> On Wed, Oct 20, 2010 at 3:11 PM, Gert Vanthienen >> <[email protected]> wrote: >>> L.S., >>> >>> We have a set of unit tests looking into error handling and conveying >>> errors between Camel routes. The intention is to make that happen as >>> seamlessly as possible, but we do have a few constraints (mostly JBI >>> specific ones) to look after. In your post, I can't see which line it >>> is that you added, but the original snippet of code you posted there >>> tries to put the exception into the fault message if that's available >>> and else put it in the JBI exception (hence forcing an ERROR exchange >>> status). Your original route probably needs a handleFault() to handle >>> the fault as if it were an error, but I can definitely take another >>> look at your example later this week (do remind me if I forget about >>> it though). >>> >>> As for the NMR, that shouldn't have the same constraints so we should >>> be able to get that working even closer to what you would expect. We >>> might get bitten by a difference in how Camel and the NMR deal with >>> faults vs errors, but there might also be gaps there in the >>> implementation of the component itself. If you could raise a JIRA >>> issue for looking into that (and perhaps add a unit test of what you >>> need), I'll gladly take a look at that as well (feel free to add a fix >>> in the patch as well, obviously ;) ) >>> >>> Regards, >>> >>> Gert Vanthienen >>> ------------------------ >>> Open Source SOA: http://fusesource.com >>> Blog: http://gertvanthienen.blogspot.com/ >>> >>> >>> >>> 2010/10/20 Björn Bength <[email protected]>: >>>> no, we tried to use the nmr component to connect camel contexts but no >>>> exception propagation here either (in our case, without defined xml >>>> soap faults), >>>> so we currently use the vm component. >>>> we haven't had time to look into it though. >>>> me too would love to here some official words on the matter before I >>>> dig into it. >>>> >>>> regards >>>> Bjorn >>>> >>>> >>>> >>>> On Wed, Oct 20, 2010 at 1:28 PM, slew <[email protected]> wrote: >>>>> >>>>> Surely I can't be the only one using jbi to connect different camel >>>>> contexts >>>>> ? Anyone else had success with this or similar problems. >>>>> >>>>> Thanks, >>>>> Steve >>>>> >>>>> >>>>> slew wrote: >>>>>> >>>>>> My "solution" is probably premature as it breaks the unit tests...but >>>>>> I >>>>>> still need to know if I'm on the right lines and there is a bug here, >>>>>> or >>>>>> if I'm just using the jbi component in a way it's not intended to be >>>>>> used. >>>>>> >>>>>> I've attached a simple test case ( >>>>>> http://servicemix.396122.n5.nabble.com/file/n3219106/TestCase-JBIFault.zip >>>>>> TestCase-JBIFault.zip ) that shows the type of thing I'm hoping to be >>>>>> able >>>>>> to do. It's no more than just being able to handle an exception that >>>>>> was >>>>>> thrown from an in-out jbi route: >>>>>> >>>>>> from("direct:test") >>>>>> .doTry() >>>>>> .to("log:Starting JBI Test") >>>>>> .to("jbi:endpoint:urn:testcase:testing?mep=in-out") >>>>>> .doCatch(SerialException.class) >>>>>> .to("log:Caught Serial exception") >>>>>> .end(); >>>>>> >>>>>> from("jbi:endpoint:urn:testcase:testing?mep=in-out") >>>>>> .errorHandler(noErrorHandler()) >>>>>> .to("log:about to throw exception?level=ERROR") >>>>>> .throwException(new SerialException("Test")); >>>>>> >>>>>> Thanks, >>>>>> Steve. >>>>>> >>>>>> >>>>>> slew wrote: >>>>>>> >>>>>>> Hi, >>>>>>> >>>>>>> Looking further into this. I can see that in >>>>>>> org.apache.servicemix.camel.CamelProviderEndpoint onFailure, the >>>>>>> camel >>>>>>> exchange details are copied to the MessageExchange, but the exception >>>>>>> is >>>>>>> not. >>>>>>> >>>>>>> If I explicitely copy the camel exception to the MessageExchange as >>>>>>> in >>>>>>> bold below, then the exception navigates the JBI NMR. >>>>>>> >>>>>>> public void onFailure(Exchange exchange) { >>>>>>> MessageExchange me = JbiBinding.getMessageExchange(exchange); >>>>>>> try { >>>>>>> if (exchange.hasOut()) { >>>>>>> Fault fault = me.createFault(); >>>>>>> me.setError(binding.extractException(exchange)); >>>>>>> binding.copyFromCamelToJbi(exchange.getOut(), fault); >>>>>>> if (isFaultCapable(me)) { >>>>>>> me.setFault(fault); >>>>>>> doSend(me); >>>>>>> } else { >>>>>>> // MessageExchange is not capable of conveying >>>>>>> faults >>>>>>> -- sending the information as an error instead >>>>>>> fail(me, new FaultException("Fault occured for " >>>>>>> + >>>>>>> exchange.getPattern() + " exchange", me, fault)); >>>>>>> } >>>>>>> } else { >>>>>>> fail(me, binding.extractException(exchange)); >>>>>>> } >>>>>>> } catch (MessagingException e) { >>>>>>> logger.warn("Unable to send JBI MessageExchange after >>>>>>> successful Camel route invocation: " + me, e); >>>>>>> } >>>>>>> } >>>>>>> >>>>>>> Please could someone with more experience than me comment on whether >>>>>>> there is anything wrong with this approach and whether it makes sense >>>>>>> to >>>>>>> raise a JIRA? >>>>>>> >>>>>>> Thanks for looking, >>>>>>> Steve. >>>>>>> >>>>>>> >>>>>>> slew wrote: >>>>>>>> >>>>>>>> Hi, >>>>>>>> >>>>>>>> I'm using camel 2.3 within smx 3.3.2. >>>>>>>> >>>>>>>> The main camel route implements a routing slip. The steps in the >>>>>>>> routing slip are made up from other jbi service assemblies, for >>>>>>>> example >>>>>>>> that do things like custom validation, auditing. The idea being >>>>>>>> that >>>>>>>> new jbi components can be deployed to smx then configured in the >>>>>>>> routing >>>>>>>> slip at runtime to modify behaviour. >>>>>>>> >>>>>>>> My first implementation used the vm component to communicate between >>>>>>>> the >>>>>>>> different camel contexts, but I was advised that this is not the >>>>>>>> correct >>>>>>>> way to do things and I should use camel's jbi component - which >>>>>>>> makes >>>>>>>> sense and was obvious once pointed out. >>>>>>>> >>>>>>>> The thing I'm not sure about is how best/correctly to propagate >>>>>>>> exceptions. When using the vm components, exceptions could be >>>>>>>> thrown in >>>>>>>> one route and caught in another, but this isn't the same for jbi as >>>>>>>> the >>>>>>>> exchange goes through the NMR. >>>>>>>> >>>>>>>> I've tried throwing an exception from the camel route with and >>>>>>>> without >>>>>>>> the convertException option set, but although the route is marked as >>>>>>>> a >>>>>>>> fault and I get a FaultException in the CamelExceptionCaught >>>>>>>> property, I >>>>>>>> lose the details of the exception. >>>>>>>> >>>>>>>> The other option I tried was setFaultBody and converting the >>>>>>>> exception >>>>>>>> to and from xml. >>>>>>>> >>>>>>>> What I'd like to know is what the recommended way to do this, so I >>>>>>>> don't >>>>>>>> end up implementing a long winded approach when there's a better >>>>>>>> alternative I just can't see. >>>>>>>> >>>>>>>> Thanks for any help, >>>>>>>> Steve. >>>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>>> >>>>> -- >>>>> View this message in context: >>>>> http://servicemix.396122.n5.nabble.com/JBI-Exception-Propagation-Advice-tp3211854p3228378.html >>>>> Sent from the ServiceMix - User mailing list archive at Nabble.com. >>>>> >>>> >>> >> >> > -- > View this message in context: > http://servicemix.396122.n5.nabble.com/JBI-Exception-Propagation-Advice-tp3211854p3228944.html > Sent from the ServiceMix - User mailing list archive at Nabble.com. >
