我有一个可以调用不同子路由的包装路由(WrapperRoute)。 我的问题是,根据子路由中的异常处理,包装路由在调用后会以不同的方式进行。
当子路由没有错误(NoErrorRoute),没有异常处理(ErrorRouteUnhandled)或处理try-catch块(ErrorRouteTryCatch)中的异常时,WrapperRoute正常工作。这意味着WrapperRoute一直工作到结束并写入最后一个日志。
当子路由具有onException-definition(ErrorRouteHandled)时,只会执行WrapperRoute中的finally块。路线的最后一个日志将不会显示。
为什么在try-catch块之后停止WrapperRoute?
这是我测试此行为的完整代码。在每个测试用例中,我都写了日志。
在测试用例中,handlingTest是WrapperRoute中缺少的最后一个日志。
package test;
import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.junit.Test;
import at.mic.edis.test.TemplateCamelTest;
public class ExcepionHandlingTest extends TemplateCamelTest{
@Test
public void noErrorTest() throws Exception {
template.sendBodyAndHeader("direct:WRAPPER", "BODY", "SUBROUTE", "direct:NO-ERROR");
// 2014-11-20 10:35:23,335 [main] INFO route1 - WRAPPER-Start
// 2014-11-20 10:35:23,350 [main] INFO route2 - NO-ERROR-ROUTE: run without exception
// 2014-11-20 10:35:23,353 [main] INFO route1 - WRAPPER: Finally
// 2014-11-20 10:35:23,353 [main] INFO route1 - WRAPPER: End of wrapper route
}
@Test
public void unhandledTest() throws Exception {
template.sendBodyAndHeader("direct:WRAPPER", "BODY", "SUBROUTE", "direct:UNHANDLED");
// 2014-11-20 10:36:34,932 [main] INFO route1 - WRAPPER-Start
// 2014-11-20 10:36:34,948 [main] INFO route3 - UNHANDLED: throw exception
// 2014-11-20 10:36:34,952 [main] INFO route1 - WRAPPER: Catch exception
// 2014-11-20 10:36:34,953 [main] INFO route1 - WRAPPER: Finally
// 2014-11-20 10:36:34,953 [main] INFO route1 - WRAPPER: End of wrapper route
}
@Test
public void handledTest() throws Exception {
template.sendBodyAndHeader("direct:WRAPPER", "BODY", "SUBROUTE", "direct:HANDLED");
// 2014-11-20 10:37:47,898 [main] INFO route1 - WRAPPER-Start
// 2014-11-20 10:37:47,913 [main] INFO route4 - HANDLED: throw exception
// 2014-11-20 10:37:47,916 [main] INFO route4 - HANDLED: Exception handled
// 2014-11-20 10:37:47,919 [main] INFO route1 - WRAPPER: Finally
}
@Test
public void tryCatchTest() throws Exception {
template.sendBodyAndHeader("direct:WRAPPER", "BODY", "SUBROUTE", "direct:TRY-CATCH");
// 2014-11-20 10:38:55,871 [main] INFO route1 - WRAPPER-Start
// 2014-11-20 10:38:55,887 [main] INFO route5 - TRY-CATCH: throw exception
// 2014-11-20 10:38:55,889 [main] INFO route5 - TRY-CATCH: exception caught
// 2014-11-20 10:38:55,890 [main] INFO route5 - TRY-CATCH: finish
// 2014-11-20 10:38:55,891 [main] INFO route1 - WRAPPER: Finally
// 2014-11-20 10:38:55,892 [main] INFO route1 - WRAPPER: End of wrapper route
}
@Override
public RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
WrapperRoute wrapper = new WrapperRoute();
NoErrorRoute noError = new NoErrorRoute();
ErrorRouteUnhandled unhandled = new ErrorRouteUnhandled();
ErrorRouteHandled handled = new ErrorRouteHandled();
ErrorRouteTryCatch tryCatch = new ErrorRouteTryCatch();
CamelContext context = getContext();
context.addRoutes(wrapper);
context.addRoutes(noError);
context.addRoutes(unhandled);
context.addRoutes(handled);
context.addRoutes(tryCatch);
}
};
}
}
WrapperRoute:
package test;
import org.apache.camel.builder.RouteBuilder;
import at.mic.edis.all.scheduler.processor.WrappedRoutingSlipBean;
public class WrapperRoute extends RouteBuilder{
@Override
public void configure() throws Exception {
onException(Exception.class)
.handled(true)
.log("WRAPPER: exception handler");
from("direct:WRAPPER")
.log("WRAPPER-Start")
.doTry()
.recipientList().method(WrappedEndpoint.class.getName())
.end()
.doCatch(Exception.class)
.log("WRAPPER: Catch exception")
.doFinally()
.log("WRAPPER: Finally")
.end()
.log("WRAPPER: End of wrapper route");
}
}
WrapperEndpoint:
package test;
import org.apache.camel.Exchange;
import org.apache.camel.Handler;
public class WrappedEndpoint {
@Handler
public Object process(Exchange exchange) throws Exception {
//Reads the direct endpoint for the subroute from the header
String endpoint = (String) exchange.getIn().getHeader("SUBROUTE");
return endpoint;
}
}
NoErrorRoute:
package test;
import org.apache.camel.builder.RouteBuilder;
public class NoErrorRoute extends RouteBuilder {
@Override
public void configure() throws Exception {
from("direct:NO-ERROR")
.log("NO-ERROR-ROUTE: run without exception");
}
}
ErrorRouteUnhandled:
package test;
import org.apache.camel.builder.RouteBuilder;
public class ErrorRouteUnhandled extends RouteBuilder{
@Override
public void configure() throws Exception {
from("direct:UNHANDLED")
.log("UNHANDLED: throw exception")
.throwException(new Exception("Exception"));
}
}
ErrorRouteHandled:
package test;
import org.apache.camel.builder.RouteBuilder;
public class ErrorRouteHandled extends RouteBuilder{
@Override
public void configure() throws Exception {
onException(Exception.class)
.handled(true)
.log("HANDLED: Exception handled");
from("direct:HANDLED")
.log("HANDLED: throw exception")
.throwException(new Exception("Exception"));
}
}
ErrorRouteTryCatch:
package test;
import org.apache.camel.builder.RouteBuilder;
public class ErrorRouteTryCatch extends RouteBuilder{
@Override
public void configure() throws Exception {
from("direct:TRY-CATCH")
.log("TRY-CATCH: throw exception")
.doTry()
.throwException(new Exception("Exception"))
.doCatch(Exception.class)
.log("TRY-CATCH: exception caught")
.end()
.log("TRY-CATCH: finish");
}
}
修改
可以将属性 Exchange.ERRORHANDLER_HANDLED (= CamelErrorHandlerHandled )设置为false。这与未定义错误处理或在onException-block中设置 .handled(false)时属性的外观相同。
我从WrapperRoute修改了doFinally() - 块,现在一切正常:
...
.doFinally()
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
// Print all properties
for (Entry<String, Object> entry: exchange.getProperties().entrySet()){
System.out.println(entry.getKey() + " | " + entry.getValue());
}
if (exchange.getProperty(Exchange.ERRORHANDLER_HANDLED)!=null){
System.out.println("Set error handler property to false");
exchange.setProperty(Exchange.ERRORHANDLER_HANDLED, false);
}
}
})
.log("WRAPPER: Finally")
.end()
...
答案 0 :(得分:0)
在handled
中将true
设置为false
(=没有返回客户端失败)到ErrorRouteHandled
,再次显示最后一个日志条目:
onException(Exception.class)
.handled(false) // changed from true to false
.log("HANDLED: Exception handled");
如果设置为true
,则只会处理doFinally()
部分中的一个步骤。
实际上,我不知道,如果这是一个错误或它是否按设计工作。