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");