Home > Enterprise >  How to create custom error response in Spring Integration using java DSL
How to create custom error response in Spring Integration using java DSL

Time:08-11

I have following simple proxy integration flow. The main task of which is to take request from the proxy send it to the actual endpoint, get the respond and send it back to the client.

@SpringBootApplication
@EnableIntegration
public class IntegrationApp {


@Value("${narko.pin}")
private String pinUrl;



public static void main(String[] args) {
    SpringApplication.run(MinzdravApplication.class, args);
}

@Bean
public DirectChannel requestPinChannel() {
    return new DirectChannel();
}

@Bean
public DirectChannel replyPinChannel() {
    return new DirectChannel();
}



@Bean
public IntegrationFlow httpProxyFlowPin() throws Exception {
    return IntegrationFlows
            .from(Http.inboundGateway("/narko/api/patient/by-pinpp")
                    .requestChannel(requestPinChannel()).replyChannel(replyPinChannel())
                    .mappedRequestHeaders("activityid")
                    .errorChannel("httpProxyErrorFlow.input")
             )
            .wireTap(sf->sf.handle(new InwardMessageHandler()))
            .enrichHeaders(h -> h.header("Content-Type", "application/json"))
            .handle(Http.outboundGateway(pinUrl).charset("utf-8")
                    .expectedResponseType(String.class))
            .channel(replyPinChannel())
            .get();
}


@Bean
public IntegrationFlow httpProxyErrorFlow() {
    return f -> f
            .transform(Throwable::getCause)
            .<HttpClientErrorException>handle((p, h) ->
                    new RuntimeException("custom exception"));
}

}

When the api at the outbound gateway is down. I have following error:

{
   "timestamp": "2022-08-10T12:51:58.561 00:00",
   "status": 500,
   "error": "Internal Server Error",
   "path": "/narko/api/patient/by-pinpp"
}

And I have following exceptions on logs:

java.lang.ClassCastException: class org.springframework.web.client.ResourceAccessException cannot be cast to class org.springframework.web.client.HttpClientErrorException (org.springframework.web.client.ResourceAccessException and org.springframework.web.client.HttpClientErrorException are in unnamed module of loader 'app')
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.integration.handler.LambdaMessageProcessor.processMessage(LambdaMessageProcessor.java:104) ~[spring-integration-core-5.5.10.jar:5.5.10]
at org.springframework.integration.handler.ServiceActivatingHandler.handleRequestMessage(ServiceActivatingHandler.java:105) ~[spring-integration-core-5.5.10.jar:5.5.10]
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:136) ~[spring-integration-core-5.5.10.jar:5.5.10]
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:56) ~[spring-integration-core-5.5.10.jar:5.5.10]
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:115) ~[spring-integration-core-5.5.10.jar:5.5.10]
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:133) ~[spring-integration-core-5.5.10.jar:5.5.10]
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:106) ~[spring-integration-core-5.5.10.jar:5.5.10]

How can I create custom exception response? Any navigation or hint is appreciated.

CodePudding user response:

First of all you don't need that .replyChannel(replyPinChannel() and .channel(replyPinChannel()). An inbound gateway sends a message with a replyChannel header, the last replying endpoint in the flow, not founding its outputChannel, will consult with that replyChannel.

Secondly, your solution about an error handler is OK, but you see yourself in the stacktrace that you just don't cast to the proper type: the ResourceAccessException is not an instance of HttpClientErrorException. Consider to expect a RestClientException instead which is a super for both ResourceAccessException and HttpClientErrorException.

  • Related