allthingssecurity opened a new pull request, #28779: URL: https://github.com/apache/camel/pull/28779
# Description [CAMEL-26421](https://issues.apache.org/jira/browse/CAMEL-26421) When a `doTry` calls another route (`direct`, `seda` with `waitForTaskToComplete`, `enrich`, ...) from its steps, or from its `doCatch` or `doFinally` blocks, the routing slip, dynamic router, multicast and recipient list of the called route do not wrap their outputs in the error handler, although the called route has its own error handler (a plain `to()` in it is redelivered as usual): - 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; - a dynamic router that counts its calls in an exchange property, as in the dynamic router documentation, loses the failure. ```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")); // without the doTry: mock:m1 gets 1 message, direct:fail 3 attempts; with it: mock:m1 gets 3 ``` Cause: `TryProcessor` sets the exchange property `TryRouteBlock` while the steps of the doTry (and its doCatch and doFinally blocks) run, so that `RoutingSlip.createErrorHandler` and `MulticastProcessor.wrapInErrorHandler` (CAMEL-7275) do not add an error handler to outputs of steps that have none. The property stayed set while the called route ran. A split is not affected: its steps are channels with the route's error handler. Changes: - `CamelInternalProcessor.RouteLifecycleAdvice` removes `TryRouteBlock` when an exchange enters a route and sets the caller's value again when the route is done. The value is the advice's state, so a route that completes asynchronously or calls itself is covered. A `doTry` inside the called route still turns off the error handler per output of its own steps. - The cost per route entry: outside a doTry, two removes on the exchange's internal properties (a remove creates no internal property map when there is none, CAMEL-26426); inside one, one remove and one put. Plus one slot in the advice state array, which the unit of work advice already allocates. - The same applies to a route called from the steps of a circuit breaker, which sets the property too: such a route now redelivers as well. - Upgrade guide (4.24): the called route can make more delivery attempts than before; when the called route handles failures (dead letter channel, or `onException` with `handled(true)`), a failed multicast output is now handled there (after its redeliveries) and no longer reaches the caller's `doCatch` (the routing slip, dynamic router and recipient list steps already had the route's error handler as a step, so for them this was already so). To turn the error handler per output off again: the EIP in a `doTry` with only a `doFinally` in the called route, or `errorHandler(noErrorHandler())` on that route (which also turns it off for its other steps). Neither option brings back the redelivery of a whole routing slip or dynamic router. Related: CAMEL-25114 restored the marker after a nested doTry (also one in a route called from a doTry). CAMEL-26332 (#28755, merged) and CAMEL-26333 (#28756) fix two other defects of a route called from a doTry, in other properties and classes (`CamelExceptionHandled`, the error-handler-handled marks of `FinallyProcessor`). CAMEL-26422 (in this batch) makes the circuit breakers restore the same marker instead of removing it. None of them conflict with this change: this branch is on a main that has #28755, and `git merge-tree` with the branches of #28756 and CAMEL-26422 is clean. With all three merged on main, the doTry/doCatch/doFinally, routing slip, recipient list, multicast and dynamic router tests of camel-core pass (478 tests, 0 failures, including the new tests of the three). #28750 (CAMEL-26327, routing slip redelivery after a nested slip) is independent: routes called from a doTry now take the same routing slip redelivery path as routes called without one, which #28750 fi xes for both. Tests: - `DoTryCalledRouteErrorHandlerTest` (camel-core, 19 tests): routing slip (also asynchronous), multicast, recipient list, dynamic router, a doCatch caller, a seda and an enrich caller, recursion, a multicast in a called route with a dead letter channel (handled there, the caller's doCatch does not run), a doTry inside the called route, and the caller's scope after a call that succeeded and after one that continued a failure. 10 fail on main and pass with the change; the other 9 (plain callers, split, a plain `to()`, a doTry inside the called route, the restore of the caller's scope) are controls that pass on both. The two restore tests fail when the restore in `after()` is replaced by a plain remove. - All tests of the core modules up to camel-core (one run): camel-core 8568 tests, 45 skipped; camel-util 320, camel-support 145 and the other core modules 0 failures. 21 camel-core tests in 6 classes failed: `RouteChecksumTest` (7), `SimpleSyntaxHintsTest` (6), `SimpleTest` (3), `FileProducerChecksumOfWrittenFileTest` (3), `FilePollEnrichDynamicFileNameTest` and `RouteWatcherReloadChangedRoutesTest`. Each of them fails the same way with the `CamelInternalProcessor` of main in my local offline build, and none of them uses a doTry. The formatter and import-sort plugins ran and changed nothing. - The new class 20 times in one JVM (380 tests) and once in each of 20 JVMs (380 tests): 0 failures. How it was found: a Rocq specification of Camel's routing semantics, written from the documentation, was compared with real Camel on generated routes; the case was then reduced to a plain Java DSL test. Backport: no, it changes the number of delivery attempts. 4.22.1 and 4.23.0 behave the same as main. # Target - [x] I checked that the commit is targeting the correct branch (Camel 4 uses the `main` branch) # Tracking - [x] If this is a large change, bug fix, or code improvement, I checked there is a [JIRA issue](https://issues.apache.org/jira/browse/CAMEL-26421) filed for the change (usually before you start working on it): [CAMEL-26421](https://issues.apache.org/jira/browse/CAMEL-26421). # Apache Camel coding standards and style - [x] I checked that each commit in the pull request has a meaningful subject line and body. - [ ] I have run `mvn clean install -DskipTests` locally from root folder and I have committed all auto-generated changes. (I built the core modules and ran the tests above, including the formatter and import-sort plugins. No generated file changes. I did not run the full root build.) # AI-assisted contributions - [x] If this PR includes AI-generated code, commits have proper co-authorship attribution (e.g., `Co-authored-by` trailers) and the PR description identifies the AI tool used. The first version of the fix was written with OpenAI Codex (GPT-6); it was then reviewed, extended (tests, upgrade guide) and verified with Claude Code (Claude Opus 5.5). The commit carries a `Co-Authored-By` trailer for each. _Claude Code on behalf of allthingssecurity_ 🤖 Generated with [Claude Code](https://claude.com/claude-code) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
