Error handling in Spring integration flow async

2019-02-25 22:20发布

问题:

I have the following Spring Integration configuration that allows me to call a gateway method from MVC Controller and letting controller return, while integration flow will continue on its own in a separate thread that does not block controller.

However, I cannot figure out how to get my error handler to work for this async flow. My gateway has error channel defined, but my exceptions do not reach it for some reason. Instead, I see that LoggingHandler gets invoked.

@Bean
IntegrationFlow mainInteractiveFlow() {
    return IntegrationFlows.from(
            MessageChannels.executor("input", executor))
            .split()
            .channel(MessageChannels.executor(executor))
            .transform(transformer)
            .handle(genericMessageHandler, "validate")
            .handle(genericMessageHandler, "checkSubscription")
            .handle(interactiveMessageService, "handle")
            .<Task, String>route(p -> p.getKind().name(),
                    m -> m.channelMapping(TaskKind.ABC.name(), "attachInteractiveChannel"))
            .get();
}

@Bean
IntegrationFlow attachInteractiveChannelFlow() {
    return IntegrationFlows.from(
            MessageChannels.direct("attachInteractiveChannel"))
            .handle(issueRouterService)
            .get();
}

@Bean
IntegrationFlow interactiveExceptionChannelFlow() {
    return IntegrationFlows.from(interactiveExceptionChannel())
            .handle(errorHandler, "handleErrorMessage")
            .get();
}

@Bean
MessageChannel interactiveExceptionChannel() {
    return MessageChannels.direct("interactiveExceptionChannel").get();
}

Gateway:

@MessagingGateway(errorChannel = "interactiveExceptionChannel")
public interface InteractiveSlackGW {

    @Gateway(requestChannel = "input")
    void interactiveMessage(Collection<Request> messages);

}

What should I do in order to see my exceptions happening in the async integration flow being handled by my error handler?

回答1:

A gateway with a void return expects no reply so there is no reply/error channel added to the message headers. When run on the calling thread, the exception is thrown to the caller; with an async flow, the exception will go to the default errorChannel (which has a log adapter attached).

For this scenario, you need to add a header enricher to set the errorChannel header to your error channel.

We should look into doing that automatically, but it does not happen currently.

I opened a JIRA Issue for this.