Repository: camel Updated Branches: refs/heads/CAMEL-11229 [created] 175c379d4
[CAMEL-11229] Avoid recursion in onException Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/175c379d Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/175c379d Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/175c379d Branch: refs/heads/CAMEL-11229 Commit: 175c379d4031b16dfdc6fcdd1c7ea2d5b8dc5a72 Parents: 215cf2b Author: Christian Schneider <ch...@die-schneider.net> Authored: Fri May 5 16:32:27 2017 +0200 Committer: Christian Schneider <ch...@die-schneider.net> Committed: Fri May 5 16:32:27 2017 +0200 ---------------------------------------------------------------------- .../camel/processor/RedeliveryErrorHandler.java | 11 ++- .../onexception/OnExceptionRecursionTest.java | 85 ++++++++++++++++++++ 2 files changed, 94 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/175c379d/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java b/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java index 51e6529..bc05bbc 100644 --- a/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java +++ b/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java @@ -851,8 +851,14 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme protected void handleException(Exchange exchange, RedeliveryData data, boolean isDeadLetterChannel) { Exception e = exchange.getException(); - // store the original caused exception in a property, so we can restore it later - exchange.setProperty(Exchange.EXCEPTION_CAUGHT, e); + Throwable origExceptionCaught = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Throwable.class); + if (origExceptionCaught != null) { + log.error("Second Exception occured inside exception handler. Failing exchange", e); + exchange.setProperty(Exchange.UNIT_OF_WORK_EXHAUSTED, true); + } else { + + // store the original caused exception in a property, so we can restore it later + exchange.setProperty(Exchange.EXCEPTION_CAUGHT, e); // find the error handler to use (if any) OnExceptionDefinition exceptionPolicy = getExceptionPolicy(exchange, e); @@ -890,6 +896,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme data.onExceptionProcessor = processor; } } + } // only log if not failure handled or not an exhausted unit of work if (!ExchangeHelper.isFailureHandled(exchange) && !ExchangeHelper.isUnitOfWorkExhausted(exchange)) { http://git-wip-us.apache.org/repos/asf/camel/blob/175c379d/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionRecursionTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionRecursionTest.java b/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionRecursionTest.java new file mode 100644 index 0000000..39c5c1b --- /dev/null +++ b/camel-core/src/test/java/org/apache/camel/processor/onexception/OnExceptionRecursionTest.java @@ -0,0 +1,85 @@ +/** + * 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.onexception; + +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.junit.Assert; + + + +/** + * Test that exceptions in an onException handler route do not go into recursion + */ +public class OnExceptionRecursionTest extends ContextTestSupport { + private int counter; + + public void testRecursion() throws Exception { + try { + template.sendBody("direct:start", "Hello World"); + } catch (CamelExecutionException e) { + Throwable inner = e.getCause(); + Assert.assertEquals("Simulate exception in route", inner.getMessage()); + } + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + onException(MyException.class).process(new Processor() { + + @Override + public void process(Exchange exchange) throws Exception { + System.out.println(); + } + }).to("direct:exhandler"); + from("direct:exhandler").process(recursionProcessor()) + .throwException(new MyException("Simulate Exception in handler route")); + from("direct:start").throwException(new MyException("Simulate exception in route")); + } + + }; + + } + + private Processor recursionProcessor() { + return new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + counter++; + if (counter > 1) { + throw new IllegalStateException("Test failed as camel would go into recursion"); + } + + } + }; + } + + class MyException extends RuntimeException { + private static final long serialVersionUID = 1L; + + MyException(String msg) { + super(msg); + } + }; + +}