【发布时间】:2017-12-12 11:25:00
【问题描述】:
我在this 线程的 cmets 部分提出了一些疑问。
在调试应用程序时,我注意到一些可能的代码错误。它们是错误还是功能?
- 在
ExpressionEvaluatingRequestHandlerAdvice::evaluateSuccessExpression中,将AdviceMessage发送到SuccessChannel后抛出异常。这会导致其中的异常有效负载。如果有异常,该方法不应该首先抛出异常吗? - 在同一个类中,
propagateOnSuccessEvaluationFailures默认为 'false' 导致不抛出异常。这反而否定了FailChannel的目的。我在外部将其设置为“true”。你能解释一下这些背后的思考过程吗?
加里已经回答了,
我不明白您的第 1 点。对于第 2 点,通常,错误处理程序会处理错误,调用者无需知道存在问题。如果存在,那么通常,错误处理程序流应该抛出一个新的异常,以向调用者指示错误处理程序已涉及。布尔值适用于您想要处理错误并将原始异常抛出给调用者的罕见实例。
我们可以在这里讨论要点,而不是使该线程混乱。
我认为第2点的解释适用于trapException。
为了说明我的观点,我复制了ExpressionEvaluatingRequestHandlerAdvice 的一部分。
protected Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) throws Exception {
try {
Object e = callback.execute();
if(this.onSuccessExpression != null) {
this.evaluateSuccessExpression(message);
}
return e;
} catch (Exception var7) {
Exception actualException = this.unwrapExceptionIfNecessary(var7);
if(this.onFailureExpression != null) {
Object evalResult = this.evaluateFailureExpression(message, actualException);
if(this.returnFailureExpressionResult) {
return evalResult;
}
}
if(!this.trapException) {
throw actualException;
} else {
return null;
}
}
}
private void evaluateSuccessExpression(Message<?> message) throws Exception {
boolean evaluationFailed = false;
Object evalResult;
try {
evalResult = this.onSuccessExpression.getValue(this.prepareEvaluationContextToUse((Exception)null), message);
} catch (Exception var5) {
evalResult = var5;
evaluationFailed = true;
}
if(this.successChannel == null && this.successChannelName != null && this.getChannelResolver() != null) {
this.successChannel = (MessageChannel)this.getChannelResolver().resolveDestination(this.successChannelName);
}
if(evalResult != null && this.successChannel != null) {
AdviceMessage resultMessage = new AdviceMessage(evalResult, message);
this.messagingTemplate.send(this.successChannel, resultMessage);
}
if(evaluationFailed && this.propagateOnSuccessEvaluationFailures) {
throw (Exception)evalResult;
}
}
private Object evaluateFailureExpression(Message<?> message, Exception exception) throws Exception {
Object evalResult;
try {
evalResult = this.onFailureExpression.getValue(this.prepareEvaluationContextToUse(exception), message);
} catch (Exception var6) {
evalResult = var6;
this.logger.error("Failure expression evaluation failed for " + message + ": " + var6.getMessage());
}
if(this.failureChannel == null && this.failureChannelName != null && this.getChannelResolver() != null) {
this.failureChannel = (MessageChannel)this.getChannelResolver().resolveDestination(this.failureChannelName);
}
if(evalResult != null && this.failureChannel != null) {
ExpressionEvaluatingRequestHandlerAdvice.MessageHandlingExpressionEvaluatingAdviceException messagingException = new ExpressionEvaluatingRequestHandlerAdvice.MessageHandlingExpressionEvaluatingAdviceException(message, "Handler Failed", this.unwrapThrowableIfNecessary(exception), evalResult);
ErrorMessage resultMessage = new ErrorMessage(messagingException);
this.messagingTemplate.send(this.failureChannel, resultMessage);
}
return evalResult;
}
在doInvoke 中,如果callback.execute() 或evaluateSuccessExpression 抛出异常,则调用evaluateFailureExpression。
现在在evaluateSuccessExpression 中,如果在评估SuccessExpression 时出现任何错误,异常将存储在evalResult 中。如果已配置,则会将其发送至SuccessChannel。如果propagateOnSuccessEvaluationFailures 设置为true,那么只有evaluateSuccessExpression 会抛出错误。由于默认设置为“false”,evalResult 不会被抛出,因此不会被evaluateFailureExpression 捕获。
即使propagateOnSuccessEvaluationFailures需要根据其他要求设置为'false',也应该在将结果发送到SuccessChannel之前检查是否抛出异常。
【问题讨论】:
标签: spring-integration spring-integration-dsl