Claus Ibsen created CAMEL-24749:
-----------------------------------

             Summary: camel-core: failover load balancer ignores 
inheritErrorHandler=false since 4.10
                 Key: CAMEL-24749
                 URL: https://issues.apache.org/jira/browse/CAMEL-24749
             Project: Camel
          Issue Type: Bug
          Components: camel-core
    Affects Versions: 4.22.0, 4.18.4, 4.10.0
            Reporter: Claus Ibsen


h3. Problem

Since 4.10.0 the {{inheritErrorHandler}} flag of the failover load balancer is 
stored but never read, so {{.loadBalance().failover(-1, false, true)}} (Java 
DSL) and {{<failoverLoadBalancer inheritErrorHandler="false"/>}} (XML / YAML) 
behave as if the flag was {{true}}: the children are still wrapped in the route 
error handler, so Camel first exhausts its redeliveries on a failing endpoint 
before the load balancer fails over, instead of failing over immediately as the 
documentation says (failoverLoadBalancer-eip.adoc, "fail over immediately on an 
error").

h3. Cause

CAMEL-21630 ({{e571a5ac2123}}) removed {{inheritErrorHandler}} from 
{{ProcessorDefinition}} as an XML attribute (it is now an {{@XmlTransient}} 
field only camel-jta sets) and moved the option onto 
{{FailoverLoadBalancerDefinition}}. Before that commit 
{{LoadBalanceDefinition.failover(...)}} called 
{{this.setInheritErrorHandler(inheritErrorHandler)}} on the load-balance node, 
which {{LoadBalanceReifier}} used when wrapping each child via 
{{wrapChannel(processor, processorType)}}. After the commit the value lands on 
the {{FailoverLoadBalancerDefinition}} and no reifier reads it: 
{{LoadBalanceReifier}} still reads {{definition.getInheritErrorHandler()}} from 
the {{LoadBalanceDefinition}} (always {{null}} outside camel-jta), and 
{{FailoverLoadBalancerReifier}} does not look at the flag at all.

h3. Reproducer

{code:java}
errorHandler(defaultErrorHandler().maximumRedeliveries(2).redeliveryDelay(0));

from("direct:start").loadBalance().failover(-1, false, true)
    .to("direct:bad").to("direct:good");

from("direct:bad").process(e -> { badCalls.incrementAndGet(); throw new 
IllegalStateException("boom"); });
from("direct:good").to("mock:good");
{code}

Expected: {{direct:bad}} is called once, then the balancer fails over to 
{{direct:good}}. Actual on 4.10+: {{direct:bad}} is called 3 times (1 + 2 
redeliveries) before failover. The existing 
{{FailOverLoadBalanceNotInheritedErrorHandlerTest}} does not catch it because 
it uses a dead letter channel, which stops the exchange either way.

h3. Fix

{{LoadBalanceReifier}} should read the flag from the 
{{FailoverLoadBalancerDefinition}} and pass it to the children's 
{{wrapChannel}}, while keeping {{inherit = true}} for the load balancer itself 
(so the route error handler can react after the failover is exhausted). Add a 
test that counts redeliveries, as above.

Affects 4.18.x and 4.22.x, should be backported to both.

Related: CAMEL-21630, CAMEL-24696.

_Claude Code on behalf of davsclaus_



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to