【发布时间】:2014-11-21 16:41:18
【问题描述】:
我有一个封装路由(WrapperRoute),它可以调用不同的子路由。 我的问题是,根据子路由中的异常处理,包装器路由在调用后会以不同的方式进行。
当子路由没有错误(NoErrorRoute)、没有异常处理(ErrorRouteUnhandled)或在try-catch块中处理异常(ErrorRouteTryCatch)时WrapperRoute正常工作。这意味着 WrapperRoute 一直工作到结束并写入最后一个日志。
当子路由有 onException-definition (ErrorRouteHandled) 时,只会执行 WrapperRoute 中的 finally-block。不会显示该路线的最后一条日志。
为什么在 try-catch 块之后停止 WrapperRoute?
这是我测试此行为的完整代码。在每个测试用例中我都写了日志。
在测试用例中,handledTest 是 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);
}
};
}
}
包装路由:
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");
}
}
包装端点:
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;
}
}
无错误路由:
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");
}
}
错误路由未处理:
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"));
}
}
错误路由处理:
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 块中设置 .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()
...
【问题讨论】:
标签: java apache-camel