Camel exception handling behaviour when using interceptor
apache-camel, java
Solution
It turns out that exceptions thrown from an `AdviceWithRouteBuilder` are not seen by the `RouteDefinition`'s `doTry/doCatch` when the route is intercepted by the `AdviceWithRouteBuilder` because they are on different channels. The way to solve this is to use a mock for the endpoint and throw the exception from the mock:
getMockEndpoint("mock:exception").whenAnyExchangeReceived(new
Processor() {
@Override
public void process(Exchange exchange) throws Exception {
throw new Exception("fail me");
}
});
See: http://camel.465427.n5.nabble.com/question-about-exception-handling-behavior-td5743489.html
Also see this issue on JIRA: https://issues.apache.org/jira/browse/CAMEL-6300 It is fixed in Camel 2.10.5 and other newer versions.
Problem
In a unit test I want to simulate that an `Exception` occurs. I expect to receive one message at the "mock:count" endpoint, because of the `doTry/doCatch`-block. Why is this not happening and why is the `Exception` handled by the general `onException`-block? ``` import org.apache.camel.LoggingLevel; import org.apache.camel.builder.AdviceWithRouteBuilder; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.mock.MockEndpoint; import org.apache.camel.test.junit4.CamelTestSupport; import org.apache.cxf.binding.soap.SoapFault; import org.junit.Test; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Text; public class TestClass extends CamelTestSupport { @Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { onException(Exception.class) .log(LoggingLevel.INFO, "outer catch") .handled(true); from("direct:start") .doTry() .to("mock:exception") .doCatch(Exception.class) .log(LoggingLevel.INFO, "inner catch") .to("mock:count") .end(); } }; } @Test public void testBlaat() throws Exception { final SoapFault soapFault = new SoapFault("Something clearly went wrong", SoapFault.FAULT_CODE_CLIENT); Element detail = soapFault.getOrCreateDetail(); Document doc = detail.getOwnerDocument(); Text tn = doc.createTextNode("Fault details"); detail.appendChild(tn); context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { interceptSendToEndpoint("mock:exception").throwException(new Exception("test")); } }); template.sendBody("direct:start", "start"); MockEndpoint endpoint = getMockEndpoint("mock:count"); endpoint.expectedMessageCount(1); assertMockEndpointsSatisfied(); } } ```