我们真的对 Spring Integration 中的错误处理感到困惑。我们使用 Boot 2.0.2 和 Kotlin。
在@Transformer
中,我们抛出异常X
。
此外,在 Java DSL 流定义中,我们抛出相同的异常 X
channel
@Bean(TO_BE_PROCESSED_CHANNEL)
fun toBeProcessed() = PublishSubscribeChannel(defaultExecutor())
流量
@Configuration
class VideoDescriptorPersistSubflow(
val videoRepository: JdbcVideoRepository,
val ingestRecordRepository: CustomIngestRecordRepository
) {
@Bean
fun videoDescriptorPersistFlow(
toBeProcessed: MessageChannel,
processedVideos: MessageChannel
) =
IntegrationFlows.from(toBeProcessed)
.filter { message: Message<*> -> message.ingestRecordId() != null }
.handle { videoDescriptor: VideoDescriptor, _ -> validateVideoDescriptor(videoDescriptor) }
.handle { videoDescriptor: VideoDescriptor, _ -> videoRepository.persist(videoDescriptor) }
.channel(processedVideos)
.get()
fun validateVideoDescriptor(videoDescriptor: VideoDescriptor): VideoDescriptor {
val errors = VideoDescriptorValidator().validate(videoDescriptor)
if (errors.isNotEmpty()) {
throw VideoMetadataValidationException(errors)
}
return videoDescriptor
}
稍后在 errorChannel
中,我们过滤掉 X
并执行一些操作。此时我们需要失败的消息。
对于 @Transformer
抛出的异常,原始消息就在那里。
对于从 java DSL 子流中抛出的消息,originalMessage 为 null。
我们做了一些挖掘并意识到,前者被包装在 MessagingExceptionWrapper
中,而后者被包装在 MessageHandlingException
中,它不包含对原始消息的引用。
有人可以帮助我们了解 Spring Integration 在什么情况下使用什么异常进行包装吗?文档在这里没有说太多,或者我们找不到任何相关内容。
更新:从 PUBSUB 更改为队列 channel 使其正常工作...
更新2:按照Gary的建议,我们现在使用payload.failed消息,效果很好。不过,ErrorMessage 中的originalMessage 存在一些狡猾的地方。
最佳答案
payload.failedMessage
是失败时的消息。 ErrorMessage.originalMessage
是流程开始时的消息。并非在所有情况下都会填充它。
关于java - Spring Integration ErrorMessage 中的 null originalMessage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50397551/