[
https://issues.apache.org/jira/browse/CAMEL-26447?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Work on CAMEL-26447 started by shashank.
----------------------------------------
> camel-core - doTry: after a doCatch caught the failure of a called route that
> failed unhandled, the later error handlers of the exchange treat it as done
> ---------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-26447
> URL: https://issues.apache.org/jira/browse/CAMEL-26447
> Project: Camel
> Issue Type: Bug
> Components: camel-core
> Reporter: shashank
> Assignee: shashank
> Priority: Minor
>
> Follow-up of CAMEL-26434 (apache/camel#28786), named in its review. Related
> to CAMEL-26333.
> When the {{doTry}} block calls a route (such as with {{direct}}) that fails
> *unhandled* (default error handler, no {{onException}}), that route's error
> handler marks the exchange as failure handled ({{failureHandled=true}},
> {{errorHandlerHandled=false}}). CAMEL-26434 clears the mark while the
> {{doCatch}} block runs, but sets it again after the block, as before. The
> mark then stays on the exchange for the rest of the calling route, so the
> error handlers that come later treat the exchange as done
> ({{RedeliveryErrorHandler.isDone}}):
> {code:java}
> // a later failure in the calling route, after the doTry
> from("direct:laterFailure")
>
> .onException(IOException.class).handled(true).to("mock:callerHandled").end()
> .doTry().to("direct:failing")
> .doCatch(IllegalArgumentException.class).to("mock:catch")
> .end()
> .throwException(new IOException("after the doTry"));
> // a route called from the doFinally after such a doCatch
> from("direct:finallyAfterCatch")
> .doTry().to("direct:failing")
> .doCatch(IllegalArgumentException.class).to("mock:catch")
> .doFinally().to("direct:dlcRoute")
> .end();
> // the doCatch throws, inside a route called by a route with a dead letter
> channel
> from("direct:outer").errorHandler(deadLetterChannel("mock:outerDead").redeliveryDelay(0))
> .to("direct:inner");
> from("direct:inner")
> .doTry().to("direct:failing")
> .doCatch(IllegalArgumentException.class).throwException(new
> IllegalStateException("in catch"))
> .end();
> from("direct:failing").throwException(new IllegalArgumentException("callee"));
> from("direct:dlcRoute").errorHandler(deadLetterChannel("mock:dead").redeliveryDelay(0))
> .throwException(new IOException("in finally"));
> {code}
> On main plus CAMEL-26434 (the result is the same on main), with the same
> routes where the {{doTry}} throws in the route itself as controls:
> ||case||doTry fails in a called route||doTry fails in the route (control)||
> |later failure in the calling route|{{IOException}}, onException not
> run|handled by onException|
> |route called from the doFinally|{{IOException: in finally}}, mock:dead
> 0|mock:dead 1|
> |doCatch throws, outer route with a DLC|{{IllegalStateException: in catch}},
> mock:outerDead 0|mock:outerDead 1|
> A route called later with a plain {{to("direct:x")}} cannot handle its
> failure either, while through a copy without the mark ({{enrich}}, {{split}})
> it can.
> *Proposal*
> * Clear the failure handled mark for good when a {{doCatch}} catches the
> exception, as for a failure in the route itself.
> * This changes what the readers of the mark see at the end of the exchange:
> {{IdempotentOnCompletion}} confirms the message instead of removing it,
> {{ResumableCompletion}} records the offset, and the JMX / Micrometer /
> OpenTelemetry {{failuresHandled}} counters no longer count it. So it needs an
> upgrade guide entry and a way back; to be designed with the fix.
> * Tests: the three cases above with their in-route controls, plus a plain
> {{to}} after the doTry.
> _Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)