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

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

commit a0e6d631065d418aea82d76766e9327c7213e559
Author: Claus Ibsen <[email protected]>
AuthorDate: Mon Aug 19 09:41:17 2024 +0200

    CAMEL-20844: UseOriginalAggregationStrategy should store caught exception 
in exchange property so the error information is accessible afterwards.
---
 .../aggregate/UseOriginalAggregationStrategy.java  | 16 +++++++++
 ...litterUseOriginalNotPropagateExceptionTest.java | 13 ++++++--
 ...UseOriginalPropagateExceptionSubRouteTest.java} | 38 ++++++++++++++++------
 ...SplitterUseOriginalPropagateExceptionTest.java} | 26 ++++++++++-----
 .../ROOT/pages/camel-4x-upgrade-guide-4_8.adoc     |  6 ++++
 5 files changed, 79 insertions(+), 20 deletions(-)

diff --git 
a/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/UseOriginalAggregationStrategy.java
 
b/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/UseOriginalAggregationStrategy.java
index 1abb39047ce..1169e71d760 100644
--- 
a/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/UseOriginalAggregationStrategy.java
+++ 
b/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/UseOriginalAggregationStrategy.java
@@ -70,6 +70,14 @@ public class UseOriginalAggregationStrategy implements 
AggregationStrategy {
                     oldExchange.setException(exception);
                 }
             }
+            exception = checkCaughtException(oldExchange, newExchange);
+            if (exception != null) {
+                if (original != null) {
+                    original.setProperty(Exchange.EXCEPTION_CAUGHT, exception);
+                } else {
+                    oldExchange.setProperty(Exchange.EXCEPTION_CAUGHT, 
exception);
+                }
+            }
         }
         return original != null ? original : oldExchange;
     }
@@ -84,6 +92,14 @@ public class UseOriginalAggregationStrategy implements 
AggregationStrategy {
         }
     }
 
+    protected Exception checkCaughtException(Exchange oldExchange, Exchange 
newExchange) {
+        Exception caught = newExchange.getProperty(Exchange.EXCEPTION_CAUGHT, 
Exception.class);
+        if (caught == null && oldExchange != null) {
+            caught = oldExchange.getProperty(Exchange.EXCEPTION_CAUGHT, 
Exception.class);
+        }
+        return caught;
+    }
+
     public Exchange getOriginal() {
         return original;
     }
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/processor/SplitterUseOriginalNotPropagateExceptionTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/processor/SplitterUseOriginalNotPropagateExceptionTest.java
index f4eb803902f..1ef4a9897a2 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/processor/SplitterUseOriginalNotPropagateExceptionTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/processor/SplitterUseOriginalNotPropagateExceptionTest.java
@@ -18,6 +18,7 @@ package org.apache.camel.processor;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
 import org.apache.camel.builder.AggregationStrategies;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.spi.CamelEvent;
@@ -26,6 +27,7 @@ import org.apache.camel.support.EventNotifierSupport;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.fail;
 
 public class SplitterUseOriginalNotPropagateExceptionTest extends 
ContextTestSupport {
@@ -40,7 +42,7 @@ public class SplitterUseOriginalNotPropagateExceptionTest 
extends ContextTestSup
     }
 
     @Test
-    public void testUseOriginalNotPropgateException() throws Exception {
+    public void testUseOriginalNotPropagateException() throws Exception {
         assertEquals(0, notifier.getErrors());
 
         getMockEndpoint("mock:line").expectedBodiesReceived("Hello", "World");
@@ -64,7 +66,14 @@ public class SplitterUseOriginalNotPropagateExceptionTest 
extends ContextTestSup
         return new RouteBuilder() {
             @Override
             public void configure() {
-                
from("direct:start").split(body()).aggregationStrategy(AggregationStrategies.useOriginal(false))
+                from("direct:start")
+                        .onCompletion().process(e -> {
+                            Exception caught = e.getException();
+                            assertNull(caught);
+                            caught = e.getProperty(Exchange.EXCEPTION_CAUGHT, 
Exception.class);
+                            assertNull(caught);
+                        }).end()
+                        
.split(body()).aggregationStrategy(AggregationStrategies.useOriginal(false))
                         .filter(simple("${body} == 'Kaboom'"))
                         .throwException(new IllegalArgumentException("Forced 
error")).end().to("mock:line").end()
                         .to("mock:result");
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/processor/SplitterUseOriginalNotPropagateExceptionTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/processor/SplitterUseOriginalPropagateExceptionSubRouteTest.java
similarity index 63%
copy from 
core/camel-core/src/test/java/org/apache/camel/processor/SplitterUseOriginalNotPropagateExceptionTest.java
copy to 
core/camel-core/src/test/java/org/apache/camel/processor/SplitterUseOriginalPropagateExceptionSubRouteTest.java
index f4eb803902f..7316c8ce647 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/processor/SplitterUseOriginalNotPropagateExceptionTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/processor/SplitterUseOriginalPropagateExceptionSubRouteTest.java
@@ -18,6 +18,7 @@ package org.apache.camel.processor;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
 import org.apache.camel.builder.AggregationStrategies;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.spi.CamelEvent;
@@ -26,9 +27,10 @@ import org.apache.camel.support.EventNotifierSupport;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.fail;
 
-public class SplitterUseOriginalNotPropagateExceptionTest extends 
ContextTestSupport {
+public class SplitterUseOriginalPropagateExceptionSubRouteTest extends 
ContextTestSupport {
 
     private final MyEventNotifier notifier = new MyEventNotifier();
 
@@ -40,23 +42,23 @@ public class SplitterUseOriginalNotPropagateExceptionTest 
extends ContextTestSup
     }
 
     @Test
-    public void testUseOriginalNotPropgateException() throws Exception {
+    public void testUseOriginalPropagateException() throws Exception {
         assertEquals(0, notifier.getErrors());
 
         getMockEndpoint("mock:line").expectedBodiesReceived("Hello", "World");
-        
getMockEndpoint("mock:result").expectedBodiesReceived("Hello,Kaboom,World");
+        getMockEndpoint("mock:result").expectedMessageCount(0);
 
         try {
             template.sendBody("direct:start", "Hello,Kaboom,World");
+            fail("Should fail");
         } catch (Exception e) {
-            fail("Should not fail");
+            // expected
         }
 
         assertMockEndpointsSatisfied();
 
-        // there should only be 1 error as we do not propagate errors to the
-        // parent
-        assertEquals(1, notifier.getErrors());
+        // there should be 1+1 error as we propagate error back to the parent
+        assertEquals(2, notifier.getErrors());
     }
 
     @Override
@@ -64,10 +66,26 @@ public class SplitterUseOriginalNotPropagateExceptionTest 
extends ContextTestSup
         return new RouteBuilder() {
             @Override
             public void configure() {
-                
from("direct:start").split(body()).aggregationStrategy(AggregationStrategies.useOriginal(false))
-                        .filter(simple("${body} == 'Kaboom'"))
-                        .throwException(new IllegalArgumentException("Forced 
error")).end().to("mock:line").end()
+                from("direct:start")
+                        .onCompletion().process(e -> {
+                            Exception caught = e.getException();
+                            assertNull(caught);
+                            caught = e.getProperty(Exchange.EXCEPTION_CAUGHT, 
Exception.class);
+                            assertIsInstanceOf(IllegalArgumentException.class, 
caught);
+                            assertEquals("Forced error", caught.getMessage());
+                        }).end()
+                        
.split(body()).aggregationStrategy(AggregationStrategies.useOriginal(true))
+                        .to("direct:sub")
+                        .end()
                         .to("mock:result");
+
+                from("direct:sub")
+                    // simulate retrying error handler
+                    
.errorHandler(defaultErrorHandler().maximumRedeliveries(3).redeliveryDelay(0))
+                    .filter(simple("${body} == 'Kaboom'"))
+                        .throwException(new IllegalArgumentException("Forced 
error"))
+                    .end()
+                    .to("mock:line");
             }
         };
     }
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/processor/SplitterUseOriginalNotPropagateExceptionTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/processor/SplitterUseOriginalPropagateExceptionTest.java
similarity index 71%
copy from 
core/camel-core/src/test/java/org/apache/camel/processor/SplitterUseOriginalNotPropagateExceptionTest.java
copy to 
core/camel-core/src/test/java/org/apache/camel/processor/SplitterUseOriginalPropagateExceptionTest.java
index f4eb803902f..3bbf4ce430e 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/processor/SplitterUseOriginalNotPropagateExceptionTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/processor/SplitterUseOriginalPropagateExceptionTest.java
@@ -18,6 +18,7 @@ package org.apache.camel.processor;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
 import org.apache.camel.builder.AggregationStrategies;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.spi.CamelEvent;
@@ -26,9 +27,10 @@ import org.apache.camel.support.EventNotifierSupport;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.fail;
 
-public class SplitterUseOriginalNotPropagateExceptionTest extends 
ContextTestSupport {
+public class SplitterUseOriginalPropagateExceptionTest extends 
ContextTestSupport {
 
     private final MyEventNotifier notifier = new MyEventNotifier();
 
@@ -40,23 +42,23 @@ public class SplitterUseOriginalNotPropagateExceptionTest 
extends ContextTestSup
     }
 
     @Test
-    public void testUseOriginalNotPropgateException() throws Exception {
+    public void testUseOriginalPropagateException() throws Exception {
         assertEquals(0, notifier.getErrors());
 
         getMockEndpoint("mock:line").expectedBodiesReceived("Hello", "World");
-        
getMockEndpoint("mock:result").expectedBodiesReceived("Hello,Kaboom,World");
+        getMockEndpoint("mock:result").expectedMessageCount(0);
 
         try {
             template.sendBody("direct:start", "Hello,Kaboom,World");
+            fail("Should fail");
         } catch (Exception e) {
-            fail("Should not fail");
+            // expected
         }
 
         assertMockEndpointsSatisfied();
 
-        // there should only be 1 error as we do not propagate errors to the
-        // parent
-        assertEquals(1, notifier.getErrors());
+        // there should be 1+1 error as we propagate error back to the parent
+        assertEquals(2, notifier.getErrors());
     }
 
     @Override
@@ -64,7 +66,15 @@ public class SplitterUseOriginalNotPropagateExceptionTest 
extends ContextTestSup
         return new RouteBuilder() {
             @Override
             public void configure() {
-                
from("direct:start").split(body()).aggregationStrategy(AggregationStrategies.useOriginal(false))
+                from("direct:start")
+                        .onCompletion().process(e -> {
+                            Exception caught = e.getException();
+                            assertNull(caught);
+                            caught = e.getProperty(Exchange.EXCEPTION_CAUGHT, 
Exception.class);
+                            assertIsInstanceOf(IllegalArgumentException.class, 
caught);
+                            assertEquals("Forced error", caught.getMessage());
+                        }).end()
+                        
.split(body()).aggregationStrategy(AggregationStrategies.useOriginal(true))
                         .filter(simple("${body} == 'Kaboom'"))
                         .throwException(new IllegalArgumentException("Forced 
error")).end().to("mock:line").end()
                         .to("mock:result");
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_8.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_8.adoc
index 3775ba0a18b..214ce003a21 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_8.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_8.adoc
@@ -6,6 +6,12 @@ from both 4.0 to 4.1 and 4.1 to 4.2.
 
 == Upgrading Camel 4.7 to 4.8
 
+=== camel-core
+
+The `UseOriginalAggregationStrategy` class will now propagate the caught 
exception stored in the exchange property `Exchange.EXCEPTION_CAUGHT`
+as well. For example when using the Splitter EIP with this, then any caught 
exception during splitting, would be stored
+as well, which allows access to this information afterward, for example in an 
`onCompletion` where the caught exception
+can be used to know some error happened during splitting.
 
 === Deprecated Components
 

Reply via email to