shashank created CAMEL-26421:
--------------------------------

             Summary: camel-core - a route called from a doTry does not use the 
error handler of its routing slip, multicast, recipient list or dynamic router: 
duplicate deliveries, no redelivery or a lost failure
                 Key: CAMEL-26421
                 URL: https://issues.apache.org/jira/browse/CAMEL-26421
             Project: Camel
          Issue Type: Bug
          Components: camel-core
            Reporter: shashank
            Assignee: shashank


When a step of a {{doTry}} calls another route ({{direct}}, {{seda}} with 
{{waitForTaskToComplete}}, {{enrich}}, ...), the EIPs of the called route that 
wrap each output in the error handler (routing slip, dynamic router, multicast, 
recipient list) do not do so (main 017f4fd11c4a). The called route has its own 
error handler, and a plain {{to()}} in it is redelivered as usual, but these 
EIPs behave as if they were in a doTry of their own:

* a routing slip redelivers the whole slip, so an endpoint that already 
succeeded gets the message again;
* a multicast or recipient list does not redeliver the failed output (one 
attempt instead of 1 + maximumRedeliveries);
* a dynamic router that counts its calls in an exchange property, as in the 
dynamic router documentation, loses the failure: the redelivery of the whole 
router "succeeds" because the bean returns null.

The same happens with a doTry that has only a doFinally, and with a route 
called from the steps of a circuit breaker.

{code:java}
onException(IllegalStateException.class).maximumRedeliveries(2).redeliveryDelay(0);
from("direct:r0").doTry().to("direct:r1").doCatch(Exception.class).to("mock:caught").end();
from("direct:r1").routingSlip(constant("mock:m1,direct:fail"));
from("direct:fail").errorHandler(noErrorHandler()).process(e -> { throw new 
IllegalStateException("boom"); });
// without the doTry: mock:m1 gets 1 message, direct:fail 3 attempts
// with it: mock:m1 gets 3 messages
{code}

*Cause*: {{TryProcessor}} sets the exchange property {{TryRouteBlock}} while 
the steps of the doTry run. {{RoutingSlip.createErrorHandler}} and 
{{MulticastProcessor.wrapInErrorHandler}} (multicast and recipient list) read 
it and leave out the error handler per output, because the steps of a doTry 
have no error handler (CAMEL-7275). The property stayed set while the called 
route ran: {{direct}} hands over the same exchange, {{seda}} and {{enrich}} 
copy it. A split is not affected (its steps are channels with the route's error 
handler).

*Fix* (proposed): {{CamelInternalProcessor.RouteLifecycleAdvice}} removes 
{{TryRouteBlock}} when an exchange enters a route and sets the caller's value 
again when the route is done (as advice state, so recursion and asynchronous 
completion are covered). A doTry inside the called route still turns off the 
error handler per output of its own steps. Upgrade guide entry: the called 
route can make more delivery attempts than before; to keep the old behaviour, 
put the EIP in a doTry of the called route or use 
{{errorHandler(noErrorHandler())}} on it.

*Tests*: {{DoTryCalledRouteErrorHandlerTest}} (camel-core, 18 tests): routing 
slip (also asynchronous), multicast, recipient list, dynamic router, doCatch, 
seda and enrich callers, recursion, a doTry inside the called route, the 
caller's scope after a successful and a failed call, and controls. 9 fail on 
main and pass with the fix. camel-core: no test class goes from passing to 
failing.

*Related*: CAMEL-25114 restored the marker after a nested doTry; CAMEL-26332 
and CAMEL-26333 fix other defects of a route called from a doTry (other 
properties and classes); the fixes combine.

*How it was found*: a Rocq specification of Camel's routing semantics, written 
from the documentation, compared with real Camel on generated routes, then 
reduced to a plain Java DSL test.

*Affected*: main, 4.23.0 and 4.22.1 (same results).

_Filed with Claude Code on behalf of allthingssecurity._



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to