在Camel中,如果在我的路由中抛出任何异常,我想将其转换为域异常并将其传递给mock:errors
端点进行测试。但我似乎无法做到。
errorHandler(deadLetterChannel("mock:errors").maximumRedeliveries(0));
// even tried this alternative while debugging the processor below
// to be sure it is not rethrown
onException(Exception.class).process((Exchange e) -> {
System.out.println(e.getException()); // breakpoint here
});
from("direct:createRequest")
.onException(Exception.class)
.handled(true)
.process(toInvalidRequestException)
.end()
.unmarshal().json(Jackson, Request.class)
.bean(validateRequest);
-------------
private static Processor toInvalidRequestException = exchange -> {
Exception e = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class);
throw new InvalidRequestException(format("Barcode request is not valid or has wrong format: %s",
getRootCauseMessage(e)), e);
};
在上面的路由中,任何异常(例如验证异常或Jackson的解析异常)都可以在某个时刻抛出。我使用onException子句拦截它,并希望将其转换为带有消息详细信息的InvalidRequestException。这有效,但后来我想断言在我的测试中使用mock:errors
端点实际抛出了这个异常。但是,该端点始终为空,因为异常不会从转换处理器传播。
我尝试了与handled(true)
和continued(true)
的组合,但我似乎无法弄明白。
答案 0 :(得分:0)
错误处理程序定义默认行为;每个错误处理程序都会有一个异常策略定义列表(通过onException
DSL创建),它将首先尝试匹配。仅当未找到匹配项时,才会应用errorHandler
的默认值。此外,由于您从onException
管道中抛出异常,因此您基本上无法完成整个错误处理流程。
比包装和重新抛出异常更好的选择是在路由构建器中使用全局onException
,将异常转换为适当类型的消息,然后执行基于消息类型/内容而不是异常类型的错误处理。
例如,这是我在当前项目中使用的有用错误消息的示例:
public class DeadLetterChannelMessage {
private String timestamp = Times.nowInUtc().toString();
private String exchangeId;
private String originalMessageBody;
private Map<String, Object> headers;
private String fromRouteId;
private String errorMessage;
private String stackTrace;
@RequiredByThirdPartyFramework("jackson")
private DeadLetterChannelMessage() {
}
@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
public DeadLetterChannelMessage(Exchange e) {
exchangeId = e.getExchangeId();
originalMessageBody = e.getIn().getBody(String.class);
headers = Collections.unmodifiableMap(e.getIn().getHeaders());
fromRouteId = e.getFromRouteId();
Optional.ofNullable(e.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class)).ifPresent(throwable -> {
errorMessage = throwable.getMessage();
stackTrace = ExceptionUtils.getStackTrace(throwable);
});
}
// getters
}
至于为什么exchange.getException()
为空 - 如果您将异常标记为已处理,则应该使用Exchange.EXCEPTION_CAUGHT
属性来获取抛出的异常:
private static Processor toInvalidRequestException = exchange -> {
Exception e = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class);
throw new InvalidRequestException(
format("Barcode request is not valid or has wrong format: %s",
getRootCauseMessage(e)), e);
};