You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2011/06/10 07:44:35 UTC

svn commit: r1134194 - in /camel/trunk: camel-core/src/main/java/org/apache/camel/builder/ camel-core/src/main/java/org/apache/camel/model/ camel-core/src/main/java/org/apache/camel/processor/ camel-core/src/test/java/org/apache/camel/issues/ camel-cor...

Author: davsclaus
Date: Fri Jun 10 05:44:34 2011
New Revision: 1134194

URL: http://svn.apache.org/viewvc?rev=1134194&view=rev
Log:
CAMEL-4041: Using FatalFallbackErrorHandler as safe fallback to catch exceptions thrown while handling another exception in onException. This avoids complicated issues with re-entrace error handling, and possible go in circles and whatnot.

Added:
    camel/trunk/camel-core/src/main/java/org/apache/camel/processor/FatalFallbackErrorHandler.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/issues/ExceptionThrownFromOnExceptionNoEndlessLoopTest.java
Modified:
    camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ErrorHandlerBuilderRef.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/model/OnExceptionDefinition.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/model/RouteDefinitionHelper.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/processor/PipelineHelper.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/issues/ExceptionCamel4022Test.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/management/EventNotifierFailureHandledEventsTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelOnExceptionOnRedeliveryTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelRedeliveryTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/ErrorHandlerOnExceptionRedeliveryAndHandledTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/MultiErrorHandlerInRouteNotHandledTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/SplitSubUnitOfWorkStopOnExceptionAndParallelTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/async/AsyncDeadLetterChannelExecutorServiceRefTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/async/AsyncDeadLetterChannelTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/async/AsyncOnExceptionFailureProcessorWithRedeliveryTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionRouteTest.java
    camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/issues/SpringExceptionCamel4022Test.xml
    camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/DeadLetterChannelOnExceptionOnRedeliveryTest.xml
    camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/SpringOnExceptionUseOriginalBodyTest.xml

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ErrorHandlerBuilderRef.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ErrorHandlerBuilderRef.java?rev=1134194&r1=1134193&r2=1134194&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ErrorHandlerBuilderRef.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ErrorHandlerBuilderRef.java Fri Jun 10 05:44:34 2011
@@ -74,7 +74,7 @@ public class ErrorHandlerBuilderRef exte
         if (!isErrorHandlerBuilderConfigured(ref)) {
             // see if there has been configured a route builder on the route
             answer = routeContext.getRoute().getErrorHandlerBuilder();
-            if (answer == null) {
+            if (answer == null && routeContext.getRoute().getErrorHandlerRef() != null) {
                 answer = routeContext.lookup(routeContext.getRoute().getErrorHandlerRef(), ErrorHandlerBuilder.class);
             }
             if (answer == null) {

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/model/OnExceptionDefinition.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/OnExceptionDefinition.java?rev=1134194&r1=1134193&r2=1134194&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/model/OnExceptionDefinition.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/OnExceptionDefinition.java Fri Jun 10 05:44:34 2011
@@ -36,6 +36,7 @@ import org.apache.camel.Route;
 import org.apache.camel.builder.ErrorHandlerBuilder;
 import org.apache.camel.builder.ExpressionBuilder;
 import org.apache.camel.processor.CatchProcessor;
+import org.apache.camel.processor.FatalFallbackErrorHandler;
 import org.apache.camel.processor.RedeliveryPolicy;
 import org.apache.camel.spi.RouteContext;
 import org.apache.camel.util.CamelContextHelper;
@@ -137,6 +138,10 @@ public class OnExceptionDefinition exten
     }
 
     public void addRoutes(RouteContext routeContext, Collection<Route> routes) throws Exception {
+        if (isInheritErrorHandler() != null && isInheritErrorHandler()) {
+            throw new IllegalArgumentException(this + " cannot have the inheritErrorHandler option set to true");
+        }
+
         setHandledFromExpressionType(routeContext);
         setContinuedFromExpressionType(routeContext);
         setRetryWhileFromExpressionType(routeContext);
@@ -154,8 +159,17 @@ public class OnExceptionDefinition exten
         }
 
         // lets attach this on exception to the route error handler
-        errorHandler = routeContext.createProcessor(this);
+        Processor child = routeContext.createProcessor(this);
+        if (child != null) {
+            // wrap in our special safe fallback error handler if OnException have child output
+            errorHandler = new FatalFallbackErrorHandler(child);
+        } else {
+            // do not wrap as there is no child output
+            errorHandler = null;
+        }
+        // lookup the error handler builder
         ErrorHandlerBuilder builder = routeContext.getRoute().getErrorHandlerBuilder();
+        // and add this as error handlers
         builder.addErrorHandlers(this);
     }
 

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java?rev=1134194&r1=1134193&r2=1134194&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java Fri Jun 10 05:44:34 2011
@@ -239,11 +239,16 @@ public abstract class ProcessorDefinitio
         // set the error handler, must be done after init as we can set the error handler as first in the chain
         if (defn instanceof TryDefinition || defn instanceof CatchDefinition || defn instanceof FinallyDefinition) {
             // do not use error handler for try .. catch .. finally blocks as it will handle errors itself
+            log.trace("{} is part of doTry .. doCatch .. doFinally so no error handler is applied", defn);
         } else if (ProcessorDefinitionHelper.isParentOfType(TryDefinition.class, defn, true)
                 || ProcessorDefinitionHelper.isParentOfType(CatchDefinition.class, defn, true)
                 || ProcessorDefinitionHelper.isParentOfType(FinallyDefinition.class, defn, true)) {
             // do not use error handler for try .. catch .. finally blocks as it will handle errors itself
             // by checking that any of our parent(s) is not a try .. catch or finally type
+            log.trace("{} is part of doTry .. doCatch .. doFinally so no error handler is applied", defn);
+        } else if (defn instanceof OnExceptionDefinition || ProcessorDefinitionHelper.isParentOfType(OnExceptionDefinition.class, defn, true)) {
+            log.trace("{} is part of OnException so no error handler is applied", defn);
+            // do not use error handler for onExceptions blocks as it will handle errors itself
         } else if (defn instanceof MulticastDefinition) {
             // do not use error handler for multicast as it offers fine grained error handlers for its outputs
             // however if share unit of work is enabled, we need to wrap an error handler on the multicast parent
@@ -251,6 +256,8 @@ public abstract class ProcessorDefinitio
             if (def.isShareUnitOfWork() && child == null) {
                 // only wrap the parent (not the children of the multicast)
                 wrapChannelInErrorHandler(channel, routeContext);
+            } else {
+                log.trace("{} is part of multicast/recipientList which have special error handling so no error handler is applied", defn);
             }
         } else if (defn instanceof RecipientListDefinition) {
             // do not use error handler for recipient list as it offers fine grained error handlers for its outputs
@@ -259,6 +266,8 @@ public abstract class ProcessorDefinitio
             if (def.isShareUnitOfWork() && child == null) {
                 // only wrap the parent (not the children of the multicast)
                 wrapChannelInErrorHandler(channel, routeContext);
+            } else {
+                log.trace("{} is part of multicast/recipientList which have special error handling so no error handler is applied", defn);
             }
         } else {
             // use error handler by default or if configured to do so

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/model/RouteDefinitionHelper.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/RouteDefinitionHelper.java?rev=1134194&r1=1134193&r2=1134194&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/model/RouteDefinitionHelper.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/RouteDefinitionHelper.java Fri Jun 10 05:44:34 2011
@@ -20,6 +20,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.builder.ErrorHandlerBuilder;
 import org.apache.camel.util.CamelContextHelper;
 import org.apache.camel.util.EndpointHelper;
 
@@ -36,24 +37,27 @@ public final class RouteDefinitionHelper
     private RouteDefinitionHelper() {
     }
 
-    public static void initParent(RouteDefinition route) {
-        for (ProcessorDefinition output : route.getOutputs()) {
-            output.setParent(route);
-            if (output.getOutputs() != null) {
-                // recursive the outputs
-                initParent(output);
+    @SuppressWarnings("unchecked")
+    public static void initParent(ProcessorDefinition parent) {
+        List<ProcessorDefinition> children = parent.getOutputs();
+        for (ProcessorDefinition child : children) {
+            child.setParent(parent);
+            if (child.getOutputs() != null && !child.getOutputs().isEmpty()) {
+                // recursive the children
+                initParent(child);
             }
         }
     }
 
     @SuppressWarnings("unchecked")
-    public static void initParent(ProcessorDefinition parent) {
+    public static void initParentAndErrorHandlerBuilder(ProcessorDefinition parent, ErrorHandlerBuilder builder) {
         List<ProcessorDefinition> children = parent.getOutputs();
         for (ProcessorDefinition child : children) {
             child.setParent(parent);
-            if (child.getOutputs() != null) {
+            child.setErrorHandlerBuilder(builder);
+            if (child.getOutputs() != null && !child.getOutputs().isEmpty()) {
                 // recursive the children
-                initParent(child);
+                initParentAndErrorHandlerBuilder(child, builder);
             }
         }
     }
@@ -102,9 +106,6 @@ public final class RouteDefinitionHelper
                                     List<InterceptSendToEndpointDefinition> interceptSendToEndpointDefinitions,
                                     List<OnCompletionDefinition> onCompletions) {
 
-        // at first init the parent
-        RouteDefinitionHelper.initParent(route);
-
         // abstracts is the cross cutting concerns
         List<ProcessorDefinition> abstracts = new ArrayList<ProcessorDefinition>();
 
@@ -116,7 +117,9 @@ public final class RouteDefinitionHelper
 
         RouteDefinitionHelper.prepareRouteForInit(route, abstracts, lower);
 
-        // interceptors should be first for the cross cutting concerns
+        // parent and error handler builder should be initialized first
+        initParentAndErrorHandlerBuilder(context, route, abstracts, onExceptions);
+        // then interceptors
         initInterceptors(context, route, abstracts, upper, intercepts, interceptFromDefinitions, interceptSendToEndpointDefinitions);
         // then on completion
         initOnCompletions(abstracts, upper, onCompletions);
@@ -131,14 +134,30 @@ public final class RouteDefinitionHelper
         route.getOutputs().addAll(0, upper);
     }
 
+    private static void initParentAndErrorHandlerBuilder(CamelContext context, RouteDefinition route,
+                                                         List<ProcessorDefinition> abstracts, List<OnExceptionDefinition> onExceptions) {
+
+        if (context != null) {
+            // let the route inherit the error handler builder from camel context if none already set
+            route.setErrorHandlerBuilderIfNull(context.getErrorHandlerBuilder());
+        }
+
+        // init parent and error handler builder on the route
+        initParentAndErrorHandlerBuilder(route, route.getErrorHandlerBuilder());
+
+        // set the parent and error handler builder on the global on exceptions
+        if (onExceptions != null) {
+            for (OnExceptionDefinition global : onExceptions) {
+                global.setErrorHandlerBuilder(context.getErrorHandlerBuilder());
+                initParentAndErrorHandlerBuilder(global, context.getErrorHandlerBuilder());
+            }
+        }
+    }
+
     private static void initOnExceptions(List<ProcessorDefinition> abstracts, List<ProcessorDefinition> upper,
                                          List<OnExceptionDefinition> onExceptions) {
         // add global on exceptions if any
         if (onExceptions != null && !onExceptions.isEmpty()) {
-            // init the parent
-            for (OnExceptionDefinition global : onExceptions) {
-                RouteDefinitionHelper.initParent(global);
-            }
             abstracts.addAll(onExceptions);
         }
 
@@ -204,7 +223,7 @@ public final class RouteDefinitionHelper
             for (InterceptDefinition intercept : intercepts) {
                 intercept.afterPropertiesSet();
                 // init the parent
-                RouteDefinitionHelper.initParent(intercept);
+                initParent(intercept);
                 // add as first output so intercept is handled before the actual route and that gives
                 // us the needed head start to init and be able to intercept all the remaining processing steps
                 upper.add(0, intercept);
@@ -239,7 +258,7 @@ public final class RouteDefinitionHelper
                 if (match) {
                     intercept.afterPropertiesSet();
                     // init the parent
-                    RouteDefinitionHelper.initParent(intercept);
+                    initParent(intercept);
                     // add as first output so intercept is handled before the actual route and that gives
                     // us the needed head start to init and be able to intercept all the remaining processing steps
                     upper.add(0, intercept);
@@ -252,7 +271,7 @@ public final class RouteDefinitionHelper
             for (InterceptSendToEndpointDefinition intercept : interceptSendToEndpointDefinitions) {
                 intercept.afterPropertiesSet();
                 // init the parent
-                RouteDefinitionHelper.initParent(intercept);
+                initParent(intercept);
                 // add as first output so intercept is handled before the actual route and that gives
                 // us the needed head start to init and be able to intercept all the remaining processing steps
                 upper.add(0, intercept);
@@ -276,7 +295,7 @@ public final class RouteDefinitionHelper
             completions = onCompletions;
             // init the parent
             for (OnCompletionDefinition global : completions) {
-                RouteDefinitionHelper.initParent(global);
+                initParent(global);
             }
         }
 

Added: camel/trunk/camel-core/src/main/java/org/apache/camel/processor/FatalFallbackErrorHandler.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/FatalFallbackErrorHandler.java?rev=1134194&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/processor/FatalFallbackErrorHandler.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/processor/FatalFallbackErrorHandler.java Fri Jun 10 05:44:34 2011
@@ -0,0 +1,73 @@
+/**
+ * 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.processor;
+
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * An {@link org.apache.camel.processor.ErrorHandler} used as a safe fallback when
+ * processing by other error handlers such as the {@link org.apache.camel.model.OnExceptionDefinition}.
+ *
+ * @version
+ */
+public class FatalFallbackErrorHandler extends DelegateAsyncProcessor implements ErrorHandler {
+
+    private static final Logger LOG = LoggerFactory.getLogger(FatalFallbackErrorHandler.class);
+
+    public FatalFallbackErrorHandler(Processor processor) {
+        super(processor);
+    }
+
+    @Override
+    protected boolean processNext(final Exchange exchange, final AsyncCallback callback) {
+        // support the asynchronous routing engine
+        boolean sync = super.processNext(exchange, new AsyncCallback() {
+            public void done(boolean doneSync) {
+                if (exchange.getException() != null) {
+                    // an exception occurred during processing onException
+
+                    // log a warning
+                    LOG.error("Exception occurred while processing exchangeId: " + exchange.getExchangeId()
+                            + " using: [" + processor + "] caused by: "
+                            + exchange.getException().getMessage(), exchange.getException());
+
+                    // we can propagated that exception to the caught property on the exchange
+                    // which will shadow any previously caught exception and cause this new exception
+                    // to be visible in the error handler
+                    exchange.setProperty(Exchange.EXCEPTION_CAUGHT, exchange.getException());
+
+                    // mark this exchange as already been error handler handled (just by having this property)
+                    // the false value mean the caught exception will be kept on the exchange, causing the
+                    // exception to be propagated back to the caller, and to break out routing
+                    exchange.setProperty(Exchange.ERRORHANDLER_HANDLED, false);
+                }
+                callback.done(doneSync);
+            }
+        });
+
+        return sync;
+    }
+
+    @Override
+    public String toString() {
+        return "FatalFallbackErrorHandler[" + processor + "]";
+    }
+}

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/processor/PipelineHelper.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/PipelineHelper.java?rev=1134194&r1=1134193&r2=1134194&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/processor/PipelineHelper.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/processor/PipelineHelper.java Fri Jun 10 05:44:34 2011
@@ -75,12 +75,10 @@ public final class PipelineHelper {
                 }
                 log.debug(sb.toString());
             }
-            
 
             return false;
         }
 
-
         // check for stop
         Object stop = exchange.getProperty(Exchange.ROUTE_STOP);
         if (stop != null) {

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/issues/ExceptionCamel4022Test.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/issues/ExceptionCamel4022Test.java?rev=1134194&r1=1134193&r2=1134194&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/issues/ExceptionCamel4022Test.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/issues/ExceptionCamel4022Test.java Fri Jun 10 05:44:34 2011
@@ -27,54 +27,62 @@ import org.apache.camel.builder.RouteBui
 public class ExceptionCamel4022Test extends ContextTestSupport {
 
     public void testExceptionWithFatalException() throws Exception {
+        getMockEndpoint("mock:a").expectedMessageCount(1);
+        getMockEndpoint("mock:b").expectedMessageCount(1);
         getMockEndpoint("mock:result").expectedMessageCount(0);
         getMockEndpoint("mock:intermediate").expectedMessageCount(0);
         getMockEndpoint("mock:onexception").expectedMessageCount(0);
-        // TODO: CAMEL-4022 should not go into DLC
-        //getMockEndpoint("mock:dlc").expectedMessageCount(0);
+        getMockEndpoint("mock:dlc").expectedMessageCount(0);
 
         try {
-            // TODO: if sending to direct:intermediate then it works as expected
             template.sendBody("direct:start", "<body/>");
-            // TODO: should fail
-            // fail("Should throw an exception");
+            fail("Should throw an exception");
         } catch (Exception e) {
             IllegalArgumentException cause = assertIsInstanceOf(IllegalArgumentException.class, e.getCause());
-            assertEquals("Forced by unit test", cause.getMessage());
+            assertEquals("Damn Again", cause.getMessage());
         }
 
         assertMockEndpointsSatisfied();
     }
 
     public static class MyExceptionThrower implements Processor {
+
+        private String msg;
+
+        public MyExceptionThrower(String msg) {
+            this.msg = msg;
+        }
+
         @Override
         public void process(Exchange exchange) throws Exception {
-            throw new IllegalArgumentException("Forced by unit test");
+            throw new IllegalArgumentException(msg);
         }
     }
 
     @Override
     protected RouteBuilder createRouteBuilder() throws Exception {
-        final Processor exceptionThrower = new MyExceptionThrower();
-
         return new RouteBuilder() {
             public void configure() {
                 // DLC
                 errorHandler(deadLetterChannel("mock:dlc").redeliveryDelay(0).maximumRedeliveries(3));
 
                 // onException that does NOT handle the exception
-                onException(IllegalArgumentException.class)
-                    .process(exceptionThrower)
+                onException(Exception.class)
+                    .logStackTrace(false)
+                    .process(new MyExceptionThrower("Damn Again"))
                     .to("mock:onexception");
 
                 // route
                 from("direct:start")
+                    .to("mock:a")
                     .to("direct:intermediate")
                     .to("mock:result2");
 
+                // 2nd route
                 from("direct:intermediate")
+                    .to("mock:b")
                     .setBody(constant("<some-value/>"))
-                    .process(exceptionThrower)
+                    .process(new MyExceptionThrower("Damn"))
                     .to("mock:intermediate");
             }
         };

Added: camel/trunk/camel-core/src/test/java/org/apache/camel/issues/ExceptionThrownFromOnExceptionNoEndlessLoopTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/issues/ExceptionThrownFromOnExceptionNoEndlessLoopTest.java?rev=1134194&view=auto
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/issues/ExceptionThrownFromOnExceptionNoEndlessLoopTest.java (added)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/issues/ExceptionThrownFromOnExceptionNoEndlessLoopTest.java Fri Jun 10 05:44:34 2011
@@ -0,0 +1,118 @@
+/**
+ * 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.issues;
+
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ * @version 
+ */
+public class ExceptionThrownFromOnExceptionNoEndlessLoopTest extends ContextTestSupport {
+
+    private static final AtomicInteger RETRY = new AtomicInteger();
+    private static final AtomicInteger ON_EXCEPTION_RETRY = new AtomicInteger();
+    private static final AtomicInteger ON_EXCEPTION_2_RETRY = new AtomicInteger();
+
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+
+    public void testExceptionThrownFromOnExceptionNoEndlessLoopTest() throws Exception {
+        RETRY.set(0);
+        ON_EXCEPTION_RETRY.set(0);
+        ON_EXCEPTION_2_RETRY.set(0);
+
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                onException(IOException.class)
+                    .maximumRedeliveries(3)
+                    .to("mock:b")
+                    .process(new Processor() {
+                        @Override
+                        public void process(Exchange exchange) throws Exception {
+                            ON_EXCEPTION_RETRY.incrementAndGet();
+                            // exception thrown here, should not trigger the
+                            // onException(IllegalArgumentException.class) as we would
+                            // then go into endless loop
+                            throw new IllegalArgumentException("Not supported");
+                        }
+                    })
+                    .to("mock:c");
+
+                onException(IllegalArgumentException.class)
+                    .to("mock:d")
+                    .process(new Processor() {
+                        @Override
+                        public void process(Exchange exchange) throws Exception {
+                            ON_EXCEPTION_2_RETRY.incrementAndGet();
+                            throw new IOException("Some other IOException");
+                        }
+                    })
+                    .to("mock:e");
+
+                from("direct:start")
+                    .to("direct:intermediate")
+                    .to("mock:result");
+
+                from("direct:intermediate")
+                    .to("mock:a")
+                    .process(new Processor() {
+                        @Override
+                        public void process(Exchange exchange) throws Exception {
+                            RETRY.incrementAndGet();
+                            throw new IOException("IO error");
+                        }
+                    })
+                    .to("mock:end");
+            }
+        });
+        context.start();
+
+        getMockEndpoint("mock:a").expectedMessageCount(1);
+        getMockEndpoint("mock:b").expectedMessageCount(1);
+        getMockEndpoint("mock:c").expectedMessageCount(0);
+        getMockEndpoint("mock:d").expectedMessageCount(0);
+        getMockEndpoint("mock:e").expectedMessageCount(0);
+        getMockEndpoint("mock:result").expectedMessageCount(0);
+        getMockEndpoint("mock:end").expectedMessageCount(0);
+
+        try {
+            template.sendBody("direct:start", "Hello World");
+            fail("Should have thrown an exception");
+        } catch (CamelExecutionException e) {
+            IllegalArgumentException cause = assertIsInstanceOf(IllegalArgumentException.class, e.getCause());
+            assertEquals("Not supported", cause.getMessage());
+        }
+
+        assertMockEndpointsSatisfied();
+
+        assertEquals("Should try 4 times (1 first, 3 retry)", 4, RETRY.get());
+        assertEquals("Should only invoke onException once", 1, ON_EXCEPTION_RETRY.get());
+        assertEquals("Should not be invoked", 0, ON_EXCEPTION_2_RETRY.get());
+    }
+
+}
+

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/management/EventNotifierFailureHandledEventsTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/management/EventNotifierFailureHandledEventsTest.java?rev=1134194&r1=1134193&r2=1134194&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/management/EventNotifierFailureHandledEventsTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/management/EventNotifierFailureHandledEventsTest.java Fri Jun 10 05:44:34 2011
@@ -127,14 +127,14 @@ public class EventNotifierFailureHandled
         assertIsInstanceOf(RouteStartedEvent.class, events.get(1));
         assertIsInstanceOf(CamelContextStartedEvent.class, events.get(2));
         assertIsInstanceOf(ExchangeCreatedEvent.class, events.get(3));
-        assertIsInstanceOf(ExchangeSentEvent.class, events.get(4));
 
-        ExchangeFailureHandledEvent e = assertIsInstanceOf(ExchangeFailureHandledEvent.class, events.get(5));
+        ExchangeFailureHandledEvent e = assertIsInstanceOf(ExchangeFailureHandledEvent.class, events.get(4));
         assertEquals("should NOT be DLC", false, e.isDeadLetterChannel());
 
-        // dead letter channel will mark the exchange as completed
-        assertIsInstanceOf(ExchangeCompletedEvent.class, events.get(6));
+        // onException will handle the exception
+        assertIsInstanceOf(ExchangeCompletedEvent.class, events.get(5));
+        assertIsInstanceOf(ExchangeSentEvent.class, events.get(6));
         assertIsInstanceOf(ExchangeSentEvent.class, events.get(7));
     }
 
-}
\ No newline at end of file
+}

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelOnExceptionOnRedeliveryTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelOnExceptionOnRedeliveryTest.java?rev=1134194&r1=1134193&r2=1134194&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelOnExceptionOnRedeliveryTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelOnExceptionOnRedeliveryTest.java Fri Jun 10 05:44:34 2011
@@ -65,7 +65,10 @@ public class DeadLetterChannelOnExceptio
                 // START SNIPPET: e1
                 // when we redeliver caused by an IOException we want to do some special
                 // code before the redeliver attempt
-                onException(IOException.class).onRedelivery(new MyIORedeliverPrcessor());
+                onException(IOException.class)
+                        // try to redeliver at most 3 times
+                        .maximumRedeliveries(3)
+                        .onRedelivery(new MyIORedeliverProcessor());
                 // END SNIPPET: e1
 
                 // START SNIPPET: e2
@@ -73,8 +76,8 @@ public class DeadLetterChannelOnExceptio
                 // MyRedeliveryProcessor before a redelivery is
                 // attempted. This allows us to alter the message before
                 errorHandler(deadLetterChannel("mock:error").maximumRedeliveries(5)
-                        .onRedelivery(new MyRedeliverPrcessor())
-                        // setting delay to zero is just to make unit teting faster
+                        .onRedelivery(new MyRedeliverProcessor())
+                        // setting delay to zero is just to make unit testing faster
                         .redeliveryDelay(0L));
                 // END SNIPPET: e2
 
@@ -89,7 +92,7 @@ public class DeadLetterChannelOnExceptio
     // START SNIPPET: e3
     // This is our processor that is executed before every redelivery attempt
     // here we can do what we want in the java code, such as altering the message
-    public static class MyRedeliverPrcessor implements Processor {
+    public static class MyRedeliverProcessor implements Processor {
 
         public void process(Exchange exchange) throws Exception {
             // the message is being redelivered so we can alter it
@@ -108,7 +111,7 @@ public class DeadLetterChannelOnExceptio
     // This is our processor that is executed before IOException redeliver attempt
     // here we can do what we want in the java code, such as altering the message
 
-    public static class MyIORedeliverPrcessor implements Processor {
+    public static class MyIORedeliverProcessor implements Processor {
 
         public void process(Exchange exchange) throws Exception {
             // just for show and tell, here we set a special header to instruct
@@ -141,4 +144,4 @@ public class DeadLetterChannelOnExceptio
     }
 
 
-}
\ No newline at end of file
+}

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelRedeliveryTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelRedeliveryTest.java?rev=1134194&r1=1134193&r2=1134194&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelRedeliveryTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelRedeliveryTest.java Fri Jun 10 05:44:34 2011
@@ -19,9 +19,7 @@ package org.apache.camel.processor;
 import org.apache.camel.ContextTestSupport;
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
-import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.component.mock.MockEndpoint;
 
 /**
  * Unit test to verify that redelivery counters is working as expected.
@@ -29,77 +27,63 @@ import org.apache.camel.component.mock.M
 public class DeadLetterChannelRedeliveryTest extends ContextTestSupport {
 
     private static int counter;
+    private static int redeliveryCounter;
 
-    public void testRedeliveryTest() throws Exception {
+    public void testTwoRedeliveryTest() throws Exception {
         counter = 0;
+        redeliveryCounter = 0;
 
-        // We expect the exchange here after 1 delivery and 2 re-deliveries
-        MockEndpoint mock = getMockEndpoint("mock:error");
-        mock.expectedMessageCount(1);
-        mock.message(0).header("CamelRedelivered").isEqualTo(Boolean.TRUE);
-        mock.message(0).header("CamelRedeliveryCounter").isEqualTo(2);
-
-        try {
-            template.sendBody("direct:start", "Hello World");
-        } catch (RuntimeCamelException e) {
-            // expected
-        }
+        getMockEndpoint("mock:error").expectedMessageCount(1);
+
+        template.sendBody("direct:two", "Hello World");
 
         assertMockEndpointsSatisfied();
 
         assertEquals(3, counter); // One call + 2 re-deliveries
+        assertEquals(2, redeliveryCounter); // 2 re-deliveries
     }
 
     public void testNoRedeliveriesTest() throws Exception {
         counter = 0;
+        redeliveryCounter = 0;
+
+        getMockEndpoint("mock:error").expectedMessageCount(1);
 
-        // We expect the exchange here after 1 delivery
-        MockEndpoint mock = getMockEndpoint("mock:no");
-        mock.expectedMessageCount(1);
-        mock.message(0).header("CamelRedelivered").isEqualTo(Boolean.FALSE);
-        mock.message(0).header("CamelRedeliveryCounter").isEqualTo(0);
-
-        try {
-            template.sendBody("direct:no", "Hello World");
-        } catch (RuntimeCamelException e) {
-            // expected
-        }
+        template.sendBody("direct:no", "Hello World");
 
         assertMockEndpointsSatisfied();
 
         assertEquals(1, counter); // One call
+        assertEquals(0, redeliveryCounter); // no redeliveries
     }
 
-    public void testOneRedeliveryTest() throws Exception {
+    public void testOneRedeliveriesTest() throws Exception {
         counter = 0;
+        redeliveryCounter = 0;
 
-        // We expect the exchange here after 1 delivery and 1 re delivery
-        MockEndpoint mock = getMockEndpoint("mock:one");
-        mock.expectedMessageCount(1);
-        mock.message(0).header("CamelRedelivered").isEqualTo(Boolean.TRUE);
-        mock.message(0).header("CamelRedeliveryCounter").isEqualTo(1);
-
-        try {
-            template.sendBody("direct:one", "Hello World");
-        } catch (RuntimeCamelException e) {
-            // expected
-        }
+        getMockEndpoint("mock:error").expectedMessageCount(1);
+
+        template.sendBody("direct:one", "Hello World");
 
         assertMockEndpointsSatisfied();
 
-        assertEquals(2, counter); // One call + 1 re-delivery
+        assertEquals(2, counter); // One call + 1 redelivery
+        assertEquals(1, redeliveryCounter); // 1 redelivery
     }
 
     @Override
     protected RouteBuilder createRouteBuilder() throws Exception {
         return new RouteBuilder() {
             public void configure() throws Exception {
-                // we use onException(Exception.class).handled(false) to instruct DLC to not handle the exception 
-                // and therefore we can assert the number of redelivery attempts to see if that works correctly
-                onException(Exception.class).handled(false);
-
-                from("direct:start")
-                    .errorHandler(deadLetterChannel("mock:error").maximumRedeliveries(2).redeliveryDelay(0))
+                from("direct:two")
+                    .errorHandler(deadLetterChannel("mock:error").maximumRedeliveries(2).redeliveryDelay(0)
+                        .onRedelivery(new Processor() {
+                            @Override
+                            public void process(Exchange exchange) throws Exception {
+                                redeliveryCounter = exchange.getIn().getHeader(Exchange.REDELIVERY_COUNTER, Integer.class);
+                            }
+                        }))
+                    // route start here
                     .process(new Processor() {
                         public void process(Exchange exchange) throws Exception {
                             counter++;
@@ -108,7 +92,14 @@ public class DeadLetterChannelRedelivery
                     });
 
                 from("direct:no")
-                    .errorHandler(deadLetterChannel("mock:no").maximumRedeliveries(0))
+                    .errorHandler(deadLetterChannel("mock:error").maximumRedeliveries(0)
+                        .onRedelivery(new Processor() {
+                            @Override
+                            public void process(Exchange exchange) throws Exception {
+                                redeliveryCounter = exchange.getIn().getHeader(Exchange.REDELIVERY_COUNTER, Integer.class);
+                            }
+                        }))
+                    // route start here
                     .process(new Processor() {
                         public void process(Exchange exchange) throws Exception {
                             counter++;
@@ -117,7 +108,14 @@ public class DeadLetterChannelRedelivery
                     });
 
                 from("direct:one")
-                    .errorHandler(deadLetterChannel("mock:one").maximumRedeliveries(1).redeliveryDelay(0))
+                    .errorHandler(deadLetterChannel("mock:error").maximumRedeliveries(1).redeliveryDelay(0)
+                            .onRedelivery(new Processor() {
+                                @Override
+                                public void process(Exchange exchange) throws Exception {
+                                    redeliveryCounter = exchange.getIn().getHeader(Exchange.REDELIVERY_COUNTER, Integer.class);
+                                }
+                            }))
+                    // route start here
                     .process(new Processor() {
                         public void process(Exchange exchange) throws Exception {
                             counter++;

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/ErrorHandlerOnExceptionRedeliveryAndHandledTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/ErrorHandlerOnExceptionRedeliveryAndHandledTest.java?rev=1134194&r1=1134193&r2=1134194&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/ErrorHandlerOnExceptionRedeliveryAndHandledTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/ErrorHandlerOnExceptionRedeliveryAndHandledTest.java Fri Jun 10 05:44:34 2011
@@ -38,14 +38,17 @@ public class ErrorHandlerOnExceptionRede
 
         try {
             template.sendBody("direct:start", "Hello World");
+            // we tried to handle that exception but then another exception occurred
+            // so this exchange failed with an exception
             fail("Should throw an exception");
         } catch (CamelExecutionException e) {
-            assertIsInstanceOf(ConnectException.class, e.getCause());
+            ConnectException cause = assertIsInstanceOf(ConnectException.class, e.getCause());
+            assertEquals("Cannot connect to bar server", cause.getMessage());
         }
 
         assertMockEndpointsSatisfied();
 
-        assertEquals("12312345", counter);
+        assertEquals("123", counter);
     }
 
     @Override
@@ -62,6 +65,7 @@ public class ErrorHandlerOnExceptionRede
                                 String s = exchange.getIn().getHeader(Exchange.REDELIVERY_COUNTER, String.class);
                                 counter += s;
                             }
+                            // we throw an exception here, but the default error handler should not kick in
                             throw new ConnectException("Cannot connect to bar server");
                         }
                     })

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/MultiErrorHandlerInRouteNotHandledTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/MultiErrorHandlerInRouteNotHandledTest.java?rev=1134194&r1=1134193&r2=1134194&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/MultiErrorHandlerInRouteNotHandledTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/MultiErrorHandlerInRouteNotHandledTest.java Fri Jun 10 05:44:34 2011
@@ -19,7 +19,6 @@ package org.apache.camel.processor;
 import org.apache.camel.ContextTestSupport;
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
-import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.mock.MockEndpoint;
 
@@ -34,6 +33,9 @@ public class MultiErrorHandlerInRouteNot
         outer.setName("Claus");
         inner.setName("James");
 
+        getMockEndpoint("mock:inner").expectedMessageCount(0);
+        getMockEndpoint("mock:outer").expectedMessageCount(0);
+
         MockEndpoint mock = getMockEndpoint("mock:end");
         mock.expectedHeaderReceived("name", "James");
 
@@ -46,17 +48,12 @@ public class MultiErrorHandlerInRouteNot
         outer.setName("Error");
         inner.setName("James");
 
+        getMockEndpoint("mock:inner").expectedMessageCount(0);
+
         MockEndpoint mock = getMockEndpoint("mock:outer");
         mock.expectedMessageCount(1);
 
-        try {
-            template.sendBody("direct:start", "Hello World");
-            fail("Should have thrown a IllegalArgumentException");
-        } catch (RuntimeCamelException e) {
-            assertTrue(e.getCause() instanceof IllegalArgumentException);
-            assertEquals("Forced exception by unit test", e.getCause().getMessage());
-            // expected
-        }
+        template.sendBody("direct:start", "Hello World");
 
         assertMockEndpointsSatisfied();
     }
@@ -65,18 +62,13 @@ public class MultiErrorHandlerInRouteNot
         outer.setName("Claus");
         inner.setName("Error");
 
+        getMockEndpoint("mock:outer").expectedMessageCount(0);
+
         MockEndpoint mock = getMockEndpoint("mock:inner");
         mock.expectedHeaderReceived("name", "Claus");
         mock.expectedMessageCount(1);
 
-        try {
-            template.sendBody("direct:start", "Hello World");
-            fail("Should have thrown a IllegalArgumentException");
-        } catch (RuntimeCamelException e) {
-            assertTrue(e.getCause() instanceof IllegalArgumentException);
-            assertEquals("Forced exception by unit test", e.getCause().getMessage());
-            // expected
-        }
+        template.sendBody("direct:start", "Hello World");
 
         assertMockEndpointsSatisfied();
     }
@@ -85,9 +77,6 @@ public class MultiErrorHandlerInRouteNot
     protected RouteBuilder createRouteBuilder() throws Exception {
         return new RouteBuilder() {
             public void configure() throws Exception {
-                // we don't want the DLC to handle the Exception
-                onException(IllegalArgumentException.class).handled(false);
-
                 from("direct:start")
                     .errorHandler(deadLetterChannel("mock:outer").maximumRedeliveries(1).redeliveryDelay(0))
                     .process(outer)
@@ -117,4 +106,4 @@ public class MultiErrorHandlerInRouteNot
         }
     }
 
-}
\ No newline at end of file
+}

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/SplitSubUnitOfWorkStopOnExceptionAndParallelTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/SplitSubUnitOfWorkStopOnExceptionAndParallelTest.java?rev=1134194&r1=1134193&r2=1134194&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/SplitSubUnitOfWorkStopOnExceptionAndParallelTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/SplitSubUnitOfWorkStopOnExceptionAndParallelTest.java Fri Jun 10 05:44:34 2011
@@ -47,8 +47,8 @@ public class SplitSubUnitOfWorkStopOnExc
 
         getMockEndpoint("mock:dead").expectedBodiesReceived("Tiger,Donkey,Camel");
         getMockEndpoint("mock:a").expectedMessageCount(1);
-        // b should get between 2 or 3 depending when we stop (we run parallel)
-        getMockEndpoint("mock:b").expectedMinimumMessageCount(2);
+        // b should get between 1 or 3 depending when we stop (we run parallel)
+        getMockEndpoint("mock:b").expectedMinimumMessageCount(1);
         getMockEndpoint("mock:result").expectedMessageCount(0);
         // line should get between 1 or 2 depending when we stop (we run parallel)
         getMockEndpoint("mock:line").expectedMinimumMessageCount(1);

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/async/AsyncDeadLetterChannelExecutorServiceRefTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/async/AsyncDeadLetterChannelExecutorServiceRefTest.java?rev=1134194&r1=1134193&r2=1134194&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/async/AsyncDeadLetterChannelExecutorServiceRefTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/async/AsyncDeadLetterChannelExecutorServiceRefTest.java Fri Jun 10 05:44:34 2011
@@ -16,12 +16,10 @@
  */
 package org.apache.camel.processor.async;
 
-import org.apache.camel.CamelExecutionException;
 import org.apache.camel.ContextTestSupport;
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.impl.ThreadPoolProfileSupport;
 import org.apache.camel.spi.ThreadPoolProfile;
 
@@ -46,12 +44,10 @@ public class AsyncDeadLetterChannelExecu
                 context.getExecutorServiceStrategy().registerThreadPoolProfile(profile);
 
                 errorHandler(deadLetterChannel("mock:dead")
-                    .maximumRedeliveries(2)
-                    .redeliveryDelay(0)
-                    .logStackTrace(false)
-                    .executorServiceRef("myAsyncPool"));
-                // we don't want the DLC to handle the exception
-                onException(Exception.class).handled(false);
+                        .maximumRedeliveries(2)
+                        .redeliveryDelay(0)
+                        .logStackTrace(false)
+                        .executorServiceRef("myAsyncPool"));
 
                 from("direct:in")
                     .threads(2)
@@ -66,20 +62,9 @@ public class AsyncDeadLetterChannelExecu
         context.start();
 
         getMockEndpoint("mock:foo").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:dead").expectedMessageCount(1);
 
-        MockEndpoint mock = getMockEndpoint("mock:dead");
-        mock.expectedMessageCount(1);
-        mock.message(0).header(Exchange.REDELIVERED).isEqualTo(Boolean.TRUE);
-        mock.message(0).header(Exchange.REDELIVERY_COUNTER).isEqualTo(2);
-        mock.message(0).header(Exchange.REDELIVERY_MAX_COUNTER).isEqualTo(2);
-
-        try {
-            template.requestBody("direct:in", "Hello World");
-            fail("Should have thrown a CamelExecutionException");
-        } catch (CamelExecutionException e) {
-            assertEquals("Forced exception by unit test", e.getCause().getMessage());
-            // expected
-        }
+        template.requestBody("direct:in", "Hello World");
 
         assertMockEndpointsSatisfied();
     }

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/async/AsyncDeadLetterChannelTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/async/AsyncDeadLetterChannelTest.java?rev=1134194&r1=1134193&r2=1134194&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/async/AsyncDeadLetterChannelTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/async/AsyncDeadLetterChannelTest.java Fri Jun 10 05:44:34 2011
@@ -16,16 +16,13 @@
  */
 package org.apache.camel.processor.async;
 
-import org.apache.camel.CamelExecutionException;
 import org.apache.camel.ContextTestSupport;
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
-import org.apache.camel.WaitForTaskToComplete;
 import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.component.mock.MockEndpoint;
 
 /**
- * Unit test to verify that error handling using async() also works as expected.
+ * Unit test to verify that error handling using threads() also works as expected.
  *
  * @version 
  */
@@ -41,8 +38,6 @@ public class AsyncDeadLetterChannelTest 
             @Override
             public void configure() throws Exception {
                 errorHandler(deadLetterChannel("mock:dead").maximumRedeliveries(2).redeliveryDelay(0).logStackTrace(false));
-                // we don't want the DLC to handle the exception
-                onException(Exception.class).handled(false);
 
                 from("direct:in")
                     .threads(2)
@@ -57,20 +52,9 @@ public class AsyncDeadLetterChannelTest 
         context.start();
 
         getMockEndpoint("mock:foo").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:dead").expectedMessageCount(1);
 
-        MockEndpoint mock = getMockEndpoint("mock:dead");
-        mock.expectedMessageCount(1);
-        mock.message(0).header(Exchange.REDELIVERED).isEqualTo(Boolean.TRUE);
-        mock.message(0).header(Exchange.REDELIVERY_COUNTER).isEqualTo(2);
-        mock.message(0).header(Exchange.REDELIVERY_MAX_COUNTER).isEqualTo(2);
-
-        try {
-            template.requestBody("direct:in", "Hello World");
-            fail("Should have thrown a CamelExecutionException");
-        } catch (CamelExecutionException e) {
-            assertEquals("Forced exception by unit test", e.getCause().getMessage());
-            // expected
-        }
+        template.requestBody("direct:in", "Hello World");
 
         assertMockEndpointsSatisfied();
     }

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/async/AsyncOnExceptionFailureProcessorWithRedeliveryTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/async/AsyncOnExceptionFailureProcessorWithRedeliveryTest.java?rev=1134194&r1=1134193&r2=1134194&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/async/AsyncOnExceptionFailureProcessorWithRedeliveryTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/async/AsyncOnExceptionFailureProcessorWithRedeliveryTest.java Fri Jun 10 05:44:34 2011
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.processor.async;
 
+import org.apache.camel.CamelExchangeException;
+import org.apache.camel.CamelExecutionException;
 import org.apache.camel.ContextTestSupport;
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
@@ -30,11 +32,16 @@ public class AsyncOnExceptionFailureProc
     private static String afterThreadName;
 
     public void testAsyncEndpoint() throws Exception {
-        getMockEndpoint("mock:error").expectedBodiesReceived("Bye Camel");
+        getMockEndpoint("mock:error").expectedMessageCount(0);
         getMockEndpoint("mock:result").expectedMessageCount(0);
 
-        String reply = template.requestBody("direct:start", "Hello Camel", String.class);
-        assertEquals("Bye Camel", reply);
+        try {
+            template.requestBody("direct:start", "Hello Camel", String.class);
+            fail("Should throw exception");
+        } catch (CamelExecutionException e) {
+            CamelExchangeException cause = assertIsInstanceOf(CamelExchangeException.class, e.getCause());
+            assertEquals("Simulated error at attempt 1. Exchange[Message: Hello Camel]", cause.getMessage());
+        }
 
         assertMockEndpointsSatisfied();
 
@@ -51,7 +58,7 @@ public class AsyncOnExceptionFailureProc
                 // use redelivery up till 5 times
                 errorHandler(defaultErrorHandler().maximumRedeliveries(5));
 
-                onException(Exception.class).handled(true)
+                onException(IllegalArgumentException.class).handled(true)
                     .process(new Processor() {
                         public void process(Exchange exchange) throws Exception {
                             beforeThreadName = Thread.currentThread().getName();
@@ -74,4 +81,4 @@ public class AsyncOnExceptionFailureProc
         };
     }
 
-}
\ No newline at end of file
+}

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionRouteTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionRouteTest.java?rev=1134194&r1=1134193&r2=1134194&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionRouteTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionRouteTest.java Fri Jun 10 05:44:34 2011
@@ -18,8 +18,8 @@ package org.apache.camel.processor.onexc
 
 import java.io.IOException;
 
+import org.apache.camel.CamelExecutionException;
 import org.apache.camel.ContextTestSupport;
-import org.apache.camel.Exchange;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.impl.JndiRegistry;
@@ -69,23 +69,26 @@ public class OnExceptionRouteTest extend
     }
 
     public void testErrorWhileHandlingException() throws Exception {
+        // DLC does not handle the exception as we failed during processing in onException
         MockEndpoint error = getMockEndpoint("mock:error");
-        error.expectedMessageCount(1);
+        error.expectedMessageCount(0);
 
         MockEndpoint mock = getMockEndpoint("mock:result");
         mock.expectedMessageCount(0);
 
-        template.sendBody("direct:start", "<order><type>myType</type><user>FuncError</user></order>");
+        try {
+            template.sendBody("direct:start", "<order><type>myType</type><user>FuncError</user></order>");
+            fail("Should have thrown an exception");
+        } catch (CamelExecutionException e) {
+            // the myOwnHandlerBean throw exception while handling an exception
+            IOException cause = assertIsInstanceOf(IOException.class, e.getCause());
+            assertEquals("Damn something did not work", cause.getMessage());
+        }
 
         assertMockEndpointsSatisfied();
 
         // should not handle it
         assertNull(myOwnHandlerBean.getPayload());
-
-        // and check that we have the caused exception stored
-        Exception cause = error.getReceivedExchanges().get(0).getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class);
-        assertIsInstanceOf(IOException.class, cause);
-        assertEquals("Damn something did not work", cause.getMessage());
     }
 
     @Override

Modified: camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/issues/SpringExceptionCamel4022Test.xml
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/issues/SpringExceptionCamel4022Test.xml?rev=1134194&r1=1134193&r2=1134194&view=diff
==============================================================================
--- camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/issues/SpringExceptionCamel4022Test.xml (original)
+++ camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/issues/SpringExceptionCamel4022Test.xml Fri Jun 10 05:44:34 2011
@@ -22,7 +22,13 @@
        http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
     ">
 
-  <bean id="MyExceptionThrower" class="org.apache.camel.issues.ExceptionCamel4022Test$MyExceptionThrower"/>
+  <bean id="MyExceptionThrowerAgain" class="org.apache.camel.issues.ExceptionCamel4022Test$MyExceptionThrower">
+    <constructor-arg index="0" value="Damn Again"/>
+  </bean>
+
+  <bean id="MyExceptionThrower" class="org.apache.camel.issues.ExceptionCamel4022Test$MyExceptionThrower">
+    <constructor-arg index="0" value="Damn"/>
+  </bean>
 
   <camelContext errorHandlerRef="dlc" xmlns="http://camel.apache.org/schema/spring">
 
@@ -32,18 +38,20 @@
 
     <onException>
       <exception>java.lang.IllegalArgumentException</exception>
-      <process ref="MyExceptionThrower"/>
+      <process ref="MyExceptionThrowerAgain"/>
       <to uri="mock:onexception"/>
     </onException>
 
     <route>
       <from uri="direct:start"/>
+      <to uri="mock:a"/>
       <to uri="direct:intermediate"/>
       <to uri="mock:result2"/>
     </route>
 
     <route>
       <from uri="direct:intermediate"/>
+      <to uri="mock:b"/>
       <setBody>
         <constant>&lt;some-value/&gt;</constant>
       </setBody>

Modified: camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/DeadLetterChannelOnExceptionOnRedeliveryTest.xml
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/DeadLetterChannelOnExceptionOnRedeliveryTest.xml?rev=1134194&r1=1134193&r2=1134194&view=diff
==============================================================================
--- camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/DeadLetterChannelOnExceptionOnRedeliveryTest.xml (original)
+++ camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/DeadLetterChannelOnExceptionOnRedeliveryTest.xml Fri Jun 10 05:44:34 2011
@@ -41,11 +41,11 @@
 
     <!-- START SNIPPET: e2 -->
     <bean id="myRedeliveryProcessor"
-          class="org.apache.camel.processor.DeadLetterChannelOnExceptionOnRedeliveryTest$MyRedeliverPrcessor"/>
+          class="org.apache.camel.processor.DeadLetterChannelOnExceptionOnRedeliveryTest$MyRedeliverProcessor"/>
     <!-- END SNIPPET: e2 -->
 
     <bean id="myIORedeliverProcessor"
-          class="org.apache.camel.processor.DeadLetterChannelOnExceptionOnRedeliveryTest$MyIORedeliverPrcessor"/>
+          class="org.apache.camel.processor.DeadLetterChannelOnExceptionOnRedeliveryTest$MyIORedeliverProcessor"/>
 
     <bean id="throwExceptionProcessor"
           class="org.apache.camel.processor.DeadLetterChannelOnExceptionOnRedeliveryTest$ThrowExceptionProcessor"/>

Modified: camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/SpringOnExceptionUseOriginalBodyTest.xml
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/SpringOnExceptionUseOriginalBodyTest.xml?rev=1134194&r1=1134193&r2=1134194&view=diff
==============================================================================
--- camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/SpringOnExceptionUseOriginalBodyTest.xml (original)
+++ camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/onexception/SpringOnExceptionUseOriginalBodyTest.xml Fri Jun 10 05:44:34 2011
@@ -41,7 +41,7 @@
         <property name="camelException" value="true"/>
     </bean>
 
-    <camelContext errorHandlerRef="deadLetter" xmlns="http://camel.apache.org/schema/spring">
+    <camelContext trace="true" errorHandlerRef="deadLetter" xmlns="http://camel.apache.org/schema/spring">
 
         <onException useOriginalMessage="true">
             <exception>java.lang.IllegalArgumentException</exception>