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)