在SpelException的情况下,ExpressionEvaluatingRequestHandlerAdvice将消息发送到成功和失败通道

时间:2017-12-12 11:25:00

标签: spring-integration spring-integration-dsl

我在this帖子的评论部分提出了一些疑问。

在调试应用程序时,我发现了一些可能的代码错误。它们是错误还是功能?

  1. DataGridView中, private void dataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e) { if(e.ColumnIndex == excelDataGridView.Columns["Links"].Index) //Handling of HyperLink Click { string cellValue = excelDataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString(); Process.Start(cellValue); //assumes the link points to the text file and opens it in the default text editor } } 发送到ExpressionEvaluatingRequestHandlerAdvice::evaluateSuccessExp‌​ression后会抛出异常。这会导致Exception有效负载。如果有的话,该方法是否应首先抛出异常?
  2. 在同一个类中,AdviceMessage默认为'false',导致不会抛出异常。这反而否定了SuccessChannel的目的。我把它设置为'true'外部。你能解释这些背后的思考过程吗?
  3. Gary回答说,

    我不明白你的意思1.对于第2点,通常,错误处理程序处理错误,并且调用者不需要知道存在问题。如果存在,那么通常,错误处理程序流应该抛出一个新的异常,以向调用者指示错误处理程序已经涉及。布尔值用于处理错误的罕见实例,并将原始异常抛给调用者。

    我们可以在这里讨论各点,而不是混乱那个线程。

    我认为第2点的解释适用于propagateOnSuccessEvaluationFailures

    为了清楚说明,我复制了FailChannel的一部分。

    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引发异常,则会调用evaluateFailureExpression

    现在在callback.execute(),如果在评估evaluateSuccessExpression时出现任何错误,则异常会存储在evaluateSuccessExpression中。如果已配置,则会将其发送到SuccessExpression。如果evalResult设置为SuccessChannel,则只有propagateOnSuccessEvaluationFailures会引发错误。由于默认情况下设置为“false”,因此不会抛出true,因此evaluateSuccessExpression无法捕获evalResult

    即使其他要求需要将evaluateFailureExpression设置为'false',也应该在将结果发送到propagateOnSuccessEvaluationFailures之前检查抛出异常。

1 个答案:

答案 0 :(得分:0)

我认为你有重点。 请提出关于此问题的JIRA,我们将修改该逻辑块。一般来说,我同意最好首先检查重新抛出,然后才将该异常发送到successChannel

不幸的是,没有解决方法(除非你自己的解决方案),我们无法立即修复它,因为它会改变行为 - 有人可能真的依赖这种现状。

我甚至认为我们可能会修改propagateOnSuccessEvaluationFailures的默认值,因为你也有点在这里。但同样重要的是:我们只能在下一个5.1版本中制作它。