当运行时异常起源于org.springframework.integration.dsl.IntegrationFlowDefinition.filter(...)方法的执行范围时,我们观察到RabbitMq中的DLQ消息缺少跟踪堆栈。
例如,使用以下代码片段:
@Bean
IntegrationFlow accountingMovementFlow(final Function<AccountingMovement, AccountingMovement> tranMoveMapValEnricher, final MessageChannel auditDiscardChannel, final Clock clock
) {
return from("dltmvChannel")
.transform(Message.class, message -> (Message<?>) MessageBuilder.fromMessage(message)
.setHeader(SINK_STARTED_TIMESTAMP, LocalDateTime.ofInstant(clock.instant(), ZoneId.of("UTC")).toString())
.build())
.transform(new AccountingMovementMapper())
.filter(AccountingMovement::isValidOperationType,
discardFlow -> discardFlow.discardChannel(auditDiscardChannel))
.filter(AccountingMovement.class, accountingMovement -> accountingMovement.getAccountBusinessDate().isBefore(accountingMovement.getMovementEffectiveDate()),
discardFlow -> discardFlow.discardChannel(auditDiscardChannel))
.transform(tranMoveMapValEnricher::apply)
.filter(AccountingMovement.class, accountingMovement -> !accountingMovement.isExistingMovement(),
discardFlow -> discardFlow.discardChannel(auditDiscardChannel))
.channel("accountingMovementEnricherChannel")
.get();
}
让我们说AccountBusinessDate为空。执行accountingMovement.getAccountBusinessDate()。isBefore(accountingMovement.getMovementEffectiveDate())将立即触发NullPointerException。在这种情况下,流入“ dltmvChannel”的消息将被存储在带有跟踪堆栈的DLQ中。但是,这没有发生。
我们跟踪/调试了.filter(...)方法,发现内部执行实际上触发了另一个解析异常,因为原始运行时异常正在冒泡。结果,DLQ的消息缺少跟踪堆栈。
我们在org.springframework.integration.dsl.IntegrationFlowDefinition的其他方法中看不到此行为。例如,如果tranMoveMapValEnricher :: apply在执行org.springframework.integration.dsl.IntegrationFlowDefinition.transform(...)时触发运行时异常,则消息将通过跟踪堆栈进行DLQ处理。