This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 25b610194e8f CAMEL-26729: camel-core - a failure seen by an 
onException that does not handle it counts as a redelivery (#29399)
25b610194e8f is described below

commit 25b610194e8fa1053acc9e6cb70cddd05b55bc5d
Author: Claus Ibsen <[email protected]>
AuthorDate: Sun Nov 8 08:20:00 2026 +0100

    CAMEL-26729: camel-core - a failure seen by an onException that does not 
handle it counts as a redelivery (#29399)
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../errorhandler/RedeliveryErrorHandler.java       |  2 +
 .../ManagedFailureWithoutRedeliveryTest.java       | 81 ++++++++++++++++++++++
 2 files changed, 83 insertions(+)

diff --git 
a/core/camel-core-processor/src/main/java/org/apache/camel/processor/errorhandler/RedeliveryErrorHandler.java
 
b/core/camel-core-processor/src/main/java/org/apache/camel/processor/errorhandler/RedeliveryErrorHandler.java
index e14b33fec0b2..28f1b4b27230 100644
--- 
a/core/camel-core-processor/src/main/java/org/apache/camel/processor/errorhandler/RedeliveryErrorHandler.java
+++ 
b/core/camel-core-processor/src/main/java/org/apache/camel/processor/errorhandler/RedeliveryErrorHandler.java
@@ -2339,6 +2339,8 @@ public abstract class RedeliveryErrorHandler extends 
ErrorHandlerSupport
             int prev = Math.max(base - 1, 0);
             in.setHeader(Exchange.REDELIVERY_COUNTER, prev);
             in.setHeader(Exchange.REDELIVERED, prev > 0 ? Boolean.TRUE : 
Boolean.FALSE);
+            // and the counter of the exchange, which 
ExchangeHelper.isRedelivered reads first (CAMEL-26729)
+            exchange.getExchangeExtension().setRedeliveryCounter(prev);
         }
 
         /**
diff --git 
a/core/camel-management/src/test/java/org/apache/camel/management/ManagedFailureWithoutRedeliveryTest.java
 
b/core/camel-management/src/test/java/org/apache/camel/management/ManagedFailureWithoutRedeliveryTest.java
new file mode 100644
index 000000000000..c9b2daf9beed
--- /dev/null
+++ 
b/core/camel-management/src/test/java/org/apache/camel/management/ManagedFailureWithoutRedeliveryTest.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.management;
+
+import javax.management.ObjectName;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledOnOs;
+import org.junit.jupiter.api.condition.OS;
+
+import static 
org.apache.camel.management.DefaultManagementObjectNameStrategy.TYPE_ROUTE;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/**
+ * An exchange that fails without a redelivery is not counted as redelivered: 
when an onException that does not handle
+ * the failure takes over, the error handler takes back the redelivery it 
counted for the failed attempt, also in the
+ * counter of the exchange that {@code ExchangeHelper.isRedelivered} reads 
since CAMEL-26712 (CAMEL-26729).
+ */
+@DisabledOnOs(OS.AIX)
+public class ManagedFailureWithoutRedeliveryTest extends ManagementTestSupport 
{
+
+    @Test
+    public void testAFailureWithoutRedeliveryIsNotARedelivery() throws 
Exception {
+        Exchange failed = template.send("direct:none", e -> 
e.getMessage().setBody("Hello"));
+
+        assertNotNull(failed.getException());
+        getMockEndpoint("mock:seen").expectedMessageCount(1);
+        getMockEndpoint("mock:seen").assertIsSatisfied();
+        assertFalse(failed.getExchangeExtension().getRedeliveryCounter() > 0);
+        assertFalse(failed.getIn().getHeader(Exchange.REDELIVERED, false, 
Boolean.class));
+        ObjectName none = getCamelObjectName(TYPE_ROUTE, "none");
+        assertEquals(1L, getMBeanServer().getAttribute(none, 
"ExchangesFailed"));
+        assertEquals(0L, getMBeanServer().getAttribute(none, "Redeliveries"));
+    }
+
+    @Test
+    public void testAFailureAfterRedeliveriesIsARedelivery() throws Exception {
+        Exchange failed = template.send("direct:twice", e -> 
e.getMessage().setBody("World"));
+
+        assertNotNull(failed.getException());
+        ObjectName twice = getCamelObjectName(TYPE_ROUTE, "twice");
+        assertEquals(1L, getMBeanServer().getAttribute(twice, 
"ExchangesFailed"));
+        assertEquals(1L, getMBeanServer().getAttribute(twice, "Redeliveries"));
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                // the failure is seen by an onException that does not handle 
it, so the error handler takes back the
+                // redelivery it counted for the failed attempt
+                from("direct:none").routeId("none")
+                        
.onException(IllegalStateException.class).to("mock:seen").end()
+                        .throwException(new IllegalStateException("Forced"));
+
+                from("direct:twice").routeId("twice")
+                        
.errorHandler(defaultErrorHandler().maximumRedeliveries(2).redeliveryDelay(0))
+                        .throwException(new IllegalStateException("Forced"));
+            }
+        };
+    }
+}

Reply via email to