0

Two IntegrationFlows are defined as follows:

@Bean
public IntegrationFlow myFlow() {
    return IntegrationFlows.from("input.channel")
            .handle("myService", "handle")
            .get();
}

@Bean
public IntegrationFlow exceptionFlow() {
    return IntegrationFlows.from("error.channel")
            .handle(m -> System.out.println(m.getHeaders()))
            .get();
}

and the handler of MyService's `handle1 method is just to print out the message and then throw an exception:

public class MyService {
    public String handle(String s) {
        System.out.println(s);
        throw new RuntimeException("error");
    }
}

In the test, a message with a defined error channel value which is exactly error.channel is put into the input.channelchannel, and it is expected to route to theerror.channel` channel.

@Test
public void myTest() {
    Message<String> m = MessageBuilder.withPayload("foo").setHeader(MessageHeaders.ERROR_CHANNEL, "error.channel").build();
    this.someInputChannel.send(m);
}

However, it throws the exception in the test and the message is not routed to the error channel.

Tonny Tc
  • 852
  • 1
  • 12
  • 37

1 Answers1

1

That's correct behavior. The errorChannel header is consulted only when there is a thread executor. Any exception is thrown to a caller as a it is done in plain Java. In case of QueueChannel and an ExecutorChannel there is an MessagePublishingErrorHandler which wraps a task call to try..catch and sends an ErrorMessage into an errorChannel header.

In your case it is just plain Java call with that this.someInputChannel.send(m); , so you get an exception directly in this main thread.

See more info in the Reference Manual: https://docs.spring.io/spring-integration/docs/current/reference/html/#namespace-errorhandler

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • 1
    You can also start the flow with a gateway instead of a simple channel - `from(MyGatewayInterface)` - and the gateway will catch the exception and route it to an error channel (if the gateway has one configured). – Gary Russell Aug 09 '19 at 13:11
  • Right, if a gateway: but the story here is about an `errorChannel` header. Anyway it looks like we need to make a `Error Handling` chapter more visible in the Reference Manual and state the point of the `errorChannel` header more clearly: too many similar questions around... – Artem Bilan Aug 09 '19 at 13:36
  • Perfect! Sounds like a sentence for our docs. Feel free to contribute such an improvement! – Artem Bilan Aug 09 '19 at 14:13
  • May I summarize the case please? 1. if all the channels are executed in one thread which means the caller itself will execute all the ops, the exception will be thrown to the caller; 2. if the caller puts a message to an asynchronous channel which means the caller's thread returns here and another thread will handle the following processes, and if there are any exceptions in the latter thread, the message will be route to the default `errorChannel` or the channel defined by the `ERROR_CHANNEL` value in message's header. Am I right? – Tonny Tc Aug 09 '19 at 14:18