我们对Spring Integration中的错误处理感到非常困惑。我们正在使用 Boot 2.0.2 和 Kotlin。
在@Transformer
内,我们抛出一个异常X
。
此外,在Java DSL流定义中,我们抛出相同的异常X
渠道
@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 子流中抛出的那个,原始消息为空。
我们做了一些挖掘并意识到,前者被包裹在MessagingExceptionWrapper
中,而后者被包裹在一个不包含对原始消息引用的MessageHandlingException
中。
有人可以帮助我们了解在什么情况下使用什么异常进行春季集成包装吗?文档在这里没有说太多,或者我们找不到任何相关内容。
更新:从 PUBSUB 更改为队列通道使其正常工作...
更新2:按照Gary的建议,我们现在使用payload.failed消息,它工作得很好。虽然在错误消息中的原始消息中有一些狡猾的东西。
payload.failedMessage
是失败时的消息。ErrorMessage.originalMessage
是流开始时的消息。并非在所有情况下都填充它。