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 2009/06/15 10:26:42 UTC

svn commit: r784685 - in /camel/trunk/camel-core/src: main/java/org/apache/camel/builder/ main/java/org/apache/camel/processor/ test/java/org/apache/camel/processor/onexception/

Author: davsclaus
Date: Mon Jun 15 08:26:42 2009
New Revision: 784685

URL: http://svn.apache.org/viewvc?rev=784685&view=rev
Log:
CAMEL-1706: DefaultErrorHandler is now as powerful as DLC.

Modified:
    camel/trunk/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryPolicy.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/ErrorOccuredInOnExceptionRoute.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/MyOwnHandlerBean.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionRouteTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionRouteWithDefaultErrorHandlerTest.java

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java?rev=784685&r1=784684&r2=784685&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java Mon Jun 15 08:26:42 2009
@@ -364,9 +364,6 @@
         RedeliveryPolicy policy = new RedeliveryPolicy();
         policy.disableRedelivery();
         policy.setRedeliverDelay(0);
-        policy.setLogStackTrace(false);
-        policy.setRetriesExhaustedLogLevel(LoggingLevel.OFF);
-        policy.setRetryAttemptedLogLevel(LoggingLevel.OFF);
         return policy;
     }
 

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java?rev=784685&r1=784684&r2=784685&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java Mon Jun 15 08:26:42 2009
@@ -127,9 +127,10 @@
             if (!shouldRedeliver) {
                 // no we should not redeliver to the same output so either try an onException (if any given)
                 // or the dead letter queue
+                boolean isDeadLetter = data.failureProcessor == null && data.deadLetterProcessor != null;
                 Processor target = data.failureProcessor != null ? data.failureProcessor : data.deadLetterProcessor;
                 // deliver to the failure processor (either an on exception or dead letter queue
-                deliverToFailureProcessor(target, exchange, data);
+                deliverToFailureProcessor(target, exchange, data, isDeadLetter);
                 // prepare the exchange for failure before returning
                 prepareExchangeAfterFailure(exchange, data);
                 // and then return
@@ -266,9 +267,11 @@
      * All redelivery attempts failed so move the exchange to the dead letter queue
      */
     protected void deliverToFailureProcessor(final Processor processor, final Exchange exchange,
-                                             final RedeliveryData data) {
+                                             final RedeliveryData data, boolean isDeadLetter) {
         // we did not success with the redelivery so now we let the failure processor handle it
-        ExchangeHelper.setFailureHandled(exchange);
+        // clear exception as we let the failure processor handle it
+        exchange.setException(null);
+
         // must decrement the redelivery counter as we didn't process the redelivery but is
         // handling by the failure handler. So we must -1 to not let the counter be out-of-sync
         decrementRedeliveryCounter(exchange);
@@ -303,8 +306,27 @@
     }
 
     protected void prepareExchangeAfterFailure(Exchange exchange, final RedeliveryData data) {
+        // we did not success with the redelivery so now we let the failure processor handle it
+        ExchangeHelper.setFailureHandled(exchange);
+
         Predicate handledPredicate = data.handledPredicate;
 
+        // honor if already set a handling
+        boolean alreadySet = exchange.getProperty(Exchange.EXCEPTION_HANDLED) != null;
+        if (alreadySet) {
+            boolean handled = exchange.getProperty(Exchange.EXCEPTION_HANDLED, Boolean.class);
+            if (log.isDebugEnabled()) {
+                log.debug("This exchange has already been marked for handling: " + handled);
+            }
+            if (handled) {
+                exchange.setException(null);
+            } else {
+                // exception not handled, put exception back in the exchange
+                exchange.setException(exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class));
+            }
+            return;
+        }
+
         if (handledPredicate == null || !handledPredicate.matches(exchange)) {
             if (log.isDebugEnabled()) {
                 log.debug("This exchange is not handled so its marked as failed: " + exchange);

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryPolicy.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryPolicy.java?rev=784685&r1=784684&r2=784685&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryPolicy.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryPolicy.java Mon Jun 15 08:26:42 2009
@@ -43,9 +43,9 @@
  *   <li>useExponentialBackOff = false</li>
  *   <li>collisionAvoidanceFactor = 0.15d</li>
  *   <li>useCollisionAvoidance = false</li>
- *   <li>retriesExhaustedLogLevel = LoggingLevel.ERROR</li>
- *   <li>retryAttemptedLogLevel = LoggingLevel.ERROR</li>
- *   <li>logStrackTrace = true</li>
+ *   <li>retriesExhaustedLogLevel = LoggingLevel.DEBUG</li>
+ *   <li>retryAttemptedLogLevel = LoggingLevel.DEBUG</li>
+ *   <li>logStrackTrace = false</li>
  * </ul>
  * <p/>
  * Setting the maximumRedeliveries to a negative value such as -1 will then always redeliver (unlimited).
@@ -82,9 +82,9 @@
     // +/-15% for a 30% spread -cgs
     protected double collisionAvoidanceFactor = 0.15d;
     protected boolean useCollisionAvoidance;
-    protected LoggingLevel retriesExhaustedLogLevel = LoggingLevel.ERROR;
-    protected LoggingLevel retryAttemptedLogLevel = LoggingLevel.ERROR;
-    protected boolean logStackTrace = true;
+    protected LoggingLevel retriesExhaustedLogLevel = LoggingLevel.DEBUG;
+    protected LoggingLevel retryAttemptedLogLevel = LoggingLevel.DEBUG;
+    protected boolean logStackTrace = false;
     protected String delayPattern;
 
     public RedeliveryPolicy() {

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/ErrorOccuredInOnExceptionRoute.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/ErrorOccuredInOnExceptionRoute.java?rev=784685&r1=784684&r2=784685&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/ErrorOccuredInOnExceptionRoute.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/ErrorOccuredInOnExceptionRoute.java Mon Jun 15 08:26:42 2009
@@ -16,9 +16,10 @@
  */
 package org.apache.camel.processor.onexception;
 
+import java.io.IOException;
+
+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;
 
 /**
@@ -26,56 +27,106 @@
  */
 public class ErrorOccuredInOnExceptionRoute extends ContextTestSupport {
 
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+
     public void testErrorInOnException() throws Exception {
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                onException(MyTechnicalException.class)
+                    .handled(true)
+                    .to("mock:tech");
+
+                onException(MyFunctionalException.class)
+                    .handled(true)
+                    .to("mock:onFunc")
+                    .throwException(new MyTechnicalException("Tech error"))
+                    .to("mock:doneFunc");
+
+                // in this regular route the processing failed
+                from("direct:start")
+                    .throwException(new MyFunctionalException("Func error"));
+            }
+        });
+        context.start();
+
         getMockEndpoint("mock:onFunc").expectedMessageCount(1);
         getMockEndpoint("mock:doneFunc").expectedMessageCount(0);
-        // TODO: should be 1 when RedeliveryErrorHandler works with exception in onException
-        getMockEndpoint("mock:tech").expectedMessageCount(0);
+        getMockEndpoint("mock:tech").expectedMessageCount(1);
+
+        template.sendBody("direct:start", "Hello World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    public void testErrorInOnExceptionNotHandledSecondOnException() throws Exception {
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                onException(IOException.class)
+                    // we cannot handle this exception so it should propagate back
+                    .to("mock:tech");
+
+                onException(MyFunctionalException.class)
+                    .handled(true)
+                    .to("mock:onFunc")
+                    .throwException(new IOException("Cannot do this"))
+                    .to("mock:doneFunc");
+
+                // in this regular route the processing failed
+                from("direct:start")
+                    .throwException(new MyFunctionalException("Func error"));
+            }
+        });
+        context.start();
+
+        getMockEndpoint("mock:onFunc").expectedMessageCount(1);
+        getMockEndpoint("mock:doneFunc").expectedMessageCount(0);
+        getMockEndpoint("mock:tech").expectedMessageCount(1);
 
         try {
             template.sendBody("direct:start", "Hello World");
-        } catch (Exception e) {
-            // TODO: this exception should not be there
-            // ignore
+            fail("Should have thrown an exception");
+        } catch (CamelExecutionException e) {
+            assertIsInstanceOf(IOException.class, e.getCause());
+            assertEquals("Cannot do this", e.getCause().getMessage());
         }
 
         assertMockEndpointsSatisfied();
     }
 
-    @Override
-    protected RouteBuilder createRouteBuilder() throws Exception {
-        return new RouteBuilder() {
+    public void testErrorInOnExceptionNotHandled() throws Exception {
+        context.addRoutes(new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                onException(MyTechnicalException.class)
-                    .handled(true)
-                    .process(new Processor() {
-                        public void process(Exchange exchange) throws Exception {
-                            // System.out.println("tech");
-                        }
-                    })
-                    .to("mock:tech");
-
                 onException(MyFunctionalException.class)
                     .handled(true)
                     .to("mock:onFunc")
-                        .process(new Processor() {
-                            public void process(Exchange exchange) throws Exception {
-                                // System.out.println("func");
-                                throw new MyTechnicalException("Tech error");
-                            }
-                        })
+                    .throwException(new IOException("Cannot do this"))
                     .to("mock:doneFunc");
 
                 // in this regular route the processing failed
                 from("direct:start")
-                    .process(new Processor() {
-                        public void process(Exchange exchange) throws Exception {
-                            throw new MyFunctionalException("Func error");
-                        }
-                    });
+                    .throwException(new MyFunctionalException("Func error"));
             }
-        };
+        });
+        context.start();
+
+        getMockEndpoint("mock:onFunc").expectedMessageCount(1);
+        getMockEndpoint("mock:doneFunc").expectedMessageCount(0);
 
+        try {
+            template.sendBody("direct:start", "Hello World");
+            fail("Should have thrown an exception");
+        } catch (CamelExecutionException e) {
+            assertIsInstanceOf(IOException.class, e.getCause());
+            assertEquals("Cannot do this", e.getCause().getMessage());
+        }
+
+        assertMockEndpointsSatisfied();
     }
+
 }

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/MyOwnHandlerBean.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/MyOwnHandlerBean.java?rev=784685&r1=784684&r2=784685&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/MyOwnHandlerBean.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/MyOwnHandlerBean.java Mon Jun 15 08:26:42 2009
@@ -24,7 +24,7 @@
 
     public void handleFailure(String payload) throws Exception {
         if (payload.indexOf("Error") > -1) {
-            throw new IOException("Damm something did not work");
+            throw new IOException("Damn something did not work");
         }
         this.payload = payload;
     }

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=784685&r1=784684&r2=784685&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 Mon Jun 15 08:26:42 2009
@@ -16,8 +16,10 @@
  */
 package org.apache.camel.processor.onexception;
 
+import java.io.IOException;
+
 import org.apache.camel.ContextTestSupport;
-import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.Exchange;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.impl.JndiRegistry;
@@ -67,21 +69,23 @@
     }
 
     public void testErrorWhileHandlingException() throws Exception {
-        getMockEndpoint("mock:error").expectedMessageCount(0);
+        MockEndpoint error = getMockEndpoint("mock:error");
+        error.expectedMessageCount(1);
 
         MockEndpoint mock = getMockEndpoint("mock:result");
         mock.expectedMessageCount(0);
 
-        try {
-            template.sendBody("direct:start", "<order><type>myType</type><user>FuncError</user></order>");
-            fail("Should throw a RuntimeCamelException");
-        } catch (RuntimeCamelException e) {
-            assertEquals("Damm something did not work", e.getCause().getMessage());
-        }
+        template.sendBody("direct:start", "<order><type>myType</type><user>FuncError</user></order>");
 
         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
@@ -107,7 +111,7 @@
                 // START SNIPPET: e1
 
                 // default should errors go to mock:error
-                errorHandler(deadLetterChannel("mock:error"));
+                errorHandler(deadLetterChannel("mock:error").redeliverDelay(0));
                 
                 // if a MyTechnicalException is thrown we will not try to redeliver and we mark it as handled
                 // so the caller does not get a failure

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionRouteWithDefaultErrorHandlerTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionRouteWithDefaultErrorHandlerTest.java?rev=784685&r1=784684&r2=784685&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionRouteWithDefaultErrorHandlerTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionRouteWithDefaultErrorHandlerTest.java Mon Jun 15 08:26:42 2009
@@ -68,7 +68,7 @@
             template.sendBody("direct:start", "<order><type>myType</type><user>FuncError</user></order>");
             fail("Should throw a RuntimeCamelException");
         } catch (RuntimeCamelException e) {
-            assertEquals("Damm something did not work", e.getCause().getMessage());
+            assertEquals("Damn something did not work", e.getCause().getMessage());
         }
 
         assertMockEndpointsSatisfied();
@@ -96,6 +96,8 @@
         return new RouteBuilder() {
             @Override
             public void configure() throws Exception {
+                errorHandler(defaultErrorHandler().maximumRedeliveries(5));
+
                 onException(MyTechnicalException.class).maximumRedeliveries(0).handled(true);
                 onException(MyFunctionalException.class).maximumRedeliveries(0).handled(true).to("bean:myOwnHandler");