[
https://issues.apache.org/jira/browse/CAMEL-26332?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Work on CAMEL-26332 started by shashank.
----------------------------------------
> camel-core - doTry: after a route called from the doTry body continued a
> failure (onException continued), no doCatch of that doTry catches a later
> exception (regression in 4.23.0)
> -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-26332
> URL: https://issues.apache.org/jira/browse/CAMEL-26332
> Project: Camel
> Issue Type: Bug
> Components: camel-core
> Reporter: shashank
> Assignee: shashank
> Priority: Major
>
> After a route called from a {{doTry}} body continued a failure
> ({{onException(...).continued(true)}}), no {{doCatch}} of that {{doTry}}
> catches a later exception in the same {{doTry}} body. The exception escapes
> the {{doTry}}, and the exchange fails where the route has a handler (main
> 8e0ce2d21371 and 4.23.0; 4.22.1 catches):
> {code:java}
> onException(NumberFormatException.class).continued(true);
> from("direct:start")
> .doTry()
> .to("direct:callee") // fails, the
> onException continues it
> .to("mock:next") // runs
> .throwException(new IllegalStateException("after the call"))
> .doCatch(IllegalStateException.class)
> .to("mock:catch") // never runs
> .end();
> from("direct:callee").throwException(new NumberFormatException("in
> callee")).to("mock:calleeEnd");
> template.send("direct:start", ...) -> mock:catch 0, exception
> IllegalStateException("after the call")
> {code}
> The same happens when the callee is called with a routing slip, a dynamic
> router or a recipient list, and when the onException redelivers before it
> continues. Without the call before the exception, or when the called route
> does not fail, the {{doCatch}} catches. The docs say that {{continued}}
> handles and continues routing "as if the exception did not occur", and that
> the first {{doCatch}} that matches is used.
> It is a regression of CAMEL-25115 (4.23.0). To keep a continued exception
> from being added as a suppressed exception of a later failure,
> {{RedeliveryErrorHandler}} now stores the continued exception in the exchange
> property {{CamelExceptionHandled}} ({{Exchange.EXCEPTION_HANDLED}}).
> {{CatchProcessor}} uses the same property to skip the other {{doCatch}}
> blocks once one of them handled the exception, and it skips the clause when
> the property has any value. {{TryProcessor}} clears the property only when
> the {{doTry}} starts, and a {{direct:}} call shares the exchange, so the
> continued failure in the called route disables every {{doCatch}} of the
> caller's {{doTry}}.
> *Fix* (proposed): {{RedeliveryErrorHandler}} keeps the continued exception
> under an exchange property of its own (a private constant), and the check of
> CAMEL-25115 compares with that property. {{CamelExceptionHandled}} is then
> again set only by a {{doCatch}} (and by a circuit breaker fallback), as in
> 4.22; {{CatchProcessor}}, {{TryProcessor}} and
> {{CatchDefinition.acceptDebugger}} are not changed. This also closes a gap in
> the CAMEL-25115 check: a {{doTry}} removed {{CamelExceptionHandled}} when it
> started, so a failure continued before a {{doTry}} was still added as a
> suppressed exception to a failure inside the {{doTry}}. A smaller change
> ({{CatchProcessor}} skips the clause only when the property is
> {{Boolean.TRUE}}) is not enough: the error handler overwrites the {{true}} of
> a {{doCatch}} that calls a route which continues a failure, and an exception
> that this {{doCatch}} then throws would be caught by the next {{doCatch}} of
> the same {{doTry}}. No upgrade guide entry: the {{doCatch}} catches again as
> in 4.22.
> *Tests*: {{DoCatchAfterContinuedFailureInCalledRouteTest}} (9 tests: a
> continued failure in a route called with {{to}}, a routing slip, a recipient
> list and a dynamic router, a continued failure after a redelivery, and a
> failure continued before the {{doTry}} that must not become a suppressed
> exception; 6 fail on main and pass with the fix. Three controls pass on main
> as well: nothing before the exception, a called route that does not fail, and
> an exception thrown by a {{doCatch}} that is not caught by the next
> {{doCatch}}). The doTry/doCatch/doFinally, onException, redelivery, dead
> letter channel, error handler, routing slip, recipient list, dynamic router
> and pipeline tests of camel-core pass (881 tests); the whole camel-core suite
> has only the known failures of the local offline build.
> *Not changed*: the circuit breaker fallbacks (camel-resilience4j,
> camel-microprofile-fault-tolerance) set {{CamelExceptionHandled}} to {{true}}
> like a {{doCatch}}, so after a fallback ran inside a {{doTry}} body a later
> exception in that body is not caught either. That is older than CAMEL-25115
> (found by reading the code, not tested) and can be a separate issue.
> *How it was found*: a Rocq specification of Camel's error handling, written
> from the documentation, was compared with real Camel on generated routes,
> then reproduced on HotSpot.
> *Affected*: main and 4.23.0 only. camel-4.22.x, 4.18.x and 4.14.x are not
> affected: there, an exception is stored in that property only by the error
> handler task used without {{onException}} and without redelivery, which never
> continues an exchange (4.22.1 catches).
> _Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)