从 ExpressionEvaluatingRequestHandlerAdvice 抛出的异常触发适配器上的错误处理程序处理程序
Exception thrown from ExpressionEvaluatingRequestHandlerAdvice triggers error handler handler on Adapter
我在我的“MessageHandler”上设置了一个建议
@ServiceActivator(inputChannel = "outbound",adviceChain = "expressionAdvice")
public MessageHandler...
并将其配置为:
@Bean
public ExpressionEvaluatingRequestHandlerAdvicer expressionAdvice() {
ExpressionEvaluatingRequestHandlerAdvice advice = new ExpressionEvaluatingRequestHandlerAdvice();
advice.setFailureChannelName("failure");
return advice;
}
在 failure
处理程序中我解析并检测错误
@ServiceActivator(inputChannel = "failure")
public void handleFailures(Message<?> message) {
ExpressionEvaluatingRequestHandlerAdvice.MessageHandlingExpressionEvaluatingAdviceException adviceException = (ExpressionEvaluatingRequestHandlerAdvice.MessageHandlingExpressionEvaluatingAdviceException) message.getPayload();
Throwable cause = adviceException.getCause().getCause().getCause();
对于特定错误,我正在执行一些操作并恢复流程。
但是对于特定的错误类型,我只是记录错误并继续,对于其他类型,我重新抛出异常以重试。
这有效,但有一个副作用,这个 throw Exception
触发了 ServiceActivator
,它是在适配器 MessageProducerSupport.setErrorChannelName
上设置的。
@ServiceActivator(inputChannel = "onerror")
它完成了工作,但我想避免调用它,只是为了重试而不去这个处理程序。
我确实需要这个处理程序来捕获来自源通道的其他类型的错误。
查看 ExpressionEvaluatingRequestHandlerAdvice
上的这个选项:
/**
* If true, any exception will be caught and null returned.
* Default false.
* @param trapException true to trap Exceptions.
*/
public void setTrapException(boolean trapException) {
更新
对于条件异常“陷阱”,您需要考虑在您的 failure
频道子流程中实现一个逻辑。但是 trapException
仍然必须是 true
.
这是我们目前在 ExpressionEvaluatingRequestHandlerAdvice
:
中的逻辑
protected Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) {
try {
Object result = callback.execute();
if (this.onSuccessExpression != null) {
evaluateSuccessExpression(message);
}
return result;
}
catch (RuntimeException e) {
Exception actualException = unwrapExceptionIfNecessary(e);
if (this.onFailureExpression != null) {
Object evalResult = evaluateFailureExpression(message, actualException);
if (this.returnFailureExpressionResult) {
return evalResult;
}
}
if (!this.trapException) {
if (e instanceof ThrowableHolderException) { // NOSONAR
throw (ThrowableHolderException) e;
}
else {
throw new ThrowableHolderException(actualException); // NOSONAR lost stack trace
}
}
return null;
}
}
因此,我们捕获了 callback.execute()
的异常并在 evaluateFailureExpression()
中处理它(它可能只是将 ErrorMessage
发送到提到的 failureChannel
)。这样的 this.messagingTemplate.send(this.failureChannel, errorMessage);
没有包装到 try..catch
中,因此如果您从错误处理流程中重新抛出异常,它将被冒泡到主流中。
我在我的“MessageHandler”上设置了一个建议
@ServiceActivator(inputChannel = "outbound",adviceChain = "expressionAdvice")
public MessageHandler...
并将其配置为:
@Bean
public ExpressionEvaluatingRequestHandlerAdvicer expressionAdvice() {
ExpressionEvaluatingRequestHandlerAdvice advice = new ExpressionEvaluatingRequestHandlerAdvice();
advice.setFailureChannelName("failure");
return advice;
}
在 failure
处理程序中我解析并检测错误
@ServiceActivator(inputChannel = "failure")
public void handleFailures(Message<?> message) {
ExpressionEvaluatingRequestHandlerAdvice.MessageHandlingExpressionEvaluatingAdviceException adviceException = (ExpressionEvaluatingRequestHandlerAdvice.MessageHandlingExpressionEvaluatingAdviceException) message.getPayload();
Throwable cause = adviceException.getCause().getCause().getCause();
对于特定错误,我正在执行一些操作并恢复流程。
但是对于特定的错误类型,我只是记录错误并继续,对于其他类型,我重新抛出异常以重试。
这有效,但有一个副作用,这个 throw Exception
触发了 ServiceActivator
,它是在适配器 MessageProducerSupport.setErrorChannelName
上设置的。
@ServiceActivator(inputChannel = "onerror")
它完成了工作,但我想避免调用它,只是为了重试而不去这个处理程序。
我确实需要这个处理程序来捕获来自源通道的其他类型的错误。
查看 ExpressionEvaluatingRequestHandlerAdvice
上的这个选项:
/**
* If true, any exception will be caught and null returned.
* Default false.
* @param trapException true to trap Exceptions.
*/
public void setTrapException(boolean trapException) {
更新
对于条件异常“陷阱”,您需要考虑在您的 failure
频道子流程中实现一个逻辑。但是 trapException
仍然必须是 true
.
这是我们目前在 ExpressionEvaluatingRequestHandlerAdvice
:
protected Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) {
try {
Object result = callback.execute();
if (this.onSuccessExpression != null) {
evaluateSuccessExpression(message);
}
return result;
}
catch (RuntimeException e) {
Exception actualException = unwrapExceptionIfNecessary(e);
if (this.onFailureExpression != null) {
Object evalResult = evaluateFailureExpression(message, actualException);
if (this.returnFailureExpressionResult) {
return evalResult;
}
}
if (!this.trapException) {
if (e instanceof ThrowableHolderException) { // NOSONAR
throw (ThrowableHolderException) e;
}
else {
throw new ThrowableHolderException(actualException); // NOSONAR lost stack trace
}
}
return null;
}
}
因此,我们捕获了 callback.execute()
的异常并在 evaluateFailureExpression()
中处理它(它可能只是将 ErrorMessage
发送到提到的 failureChannel
)。这样的 this.messagingTemplate.send(this.failureChannel, errorMessage);
没有包装到 try..catch
中,因此如果您从错误处理流程中重新抛出异常,它将被冒泡到主流中。