[ 
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)

Reply via email to