SharifS
SharifS

Reputation: 90

How to use custom error channel to produce custom error response?

I am trying to build a simple API using Spring Integration. For any exceptions or errors thrown in the API, I want to provide custom error responses to client. I am trying with the flow structure below:

@Bean
public IntegrationFlow mainFlow() {
    return IntegrationFlows.from(WebFlux.inboundGateway(path)
            .errorChannel(customErrorChannel())
        )
        .enrichHeaders(h -> h.header(MessageHeaders.ERROR_CHANNEL, "customErrorChannel"))
        .transform(p -> {
            if(<some validation fails>)
                throw new RuntimeException("Error!");
            return "Ok Response";
        })
        .get();
}

@Bean
public PublishSubscribeChannel customErrorChannel() {
    return MessageChannels.publishSubscribe().get();
}

@Bean
public IntegrationFlow errorFlow() {
    return IntegrationFlows.from("customErrorChannel")
        .transform(p -> {
            return "Error Response";
        })
        .get();
}

For success cases, "Ok Response" is provided to the client. But when exception is thrown in transformer, provided response is default error response from the framework with stack trace. How can I use errorFlow to produce final response for exceptions?

I can use CustomErrorWebExceptionHandler as global exception handler, but that is not my intention.

Upvotes: 0

Views: 946

Answers (1)

Artem Bilan
Artem Bilan

Reputation: 121272

It turns out that the .errorChannel(customErrorChannel()) is out of use in case of reactive channel adapter like that WebFlux.inboundGateway(). Please, raise a GH issue and we'll think what and how we can do.

As a workaround I suggest you to take a look into an ExpressionEvaluatingRequestHandlerAdvice for that transform(): https://docs.spring.io/spring-integration/docs/current/reference/html/messaging-endpoints.html#message-handler-advice-chain.

This way you'll catch all the errors in the transformer and can send them to your customErrorChannel for handling.

There is no reason in the .enrichHeaders(h -> h.header(MessageHeaders.ERROR_CHANNEL, "customErrorChannel")) though. The .errorChannel(customErrorChannel()) should be enough. But when we have a fix already.

UPDATE

Turns out as a workaround you can add .channel(MessageChannels.flux()) before your transform() and the error should be process through your errorChannel.

Upvotes: 1

Related Questions