1
votes

I'm trying to configure an error channel for Spring Cloud Azure Service Bus Queue Stream Binder with no success. I've enabled the error channel via

spring:
  cloud:
    stream:
      function:
        definition: produce
      bindings:
        produce-out-0:
          destination: service-bus-q-a
          producer:
            error-channel-enabled: true

And tried defining a @ServiceActivator:

@ServiceActivator(inputChannel = "service-bus-q-a.errors")
public void errors(ErrorMessage receiveMsg) {
    System.err.println("receive error msg: " + receiveMsg);
}

I've also tried on inputChannel = "errorChannel" and inputChannel = "service-bus-q-a.$Default.errors". Obviously I am missing something here but I couldn't find a working example.

EDIT: I'm using the following Supplier bean:

@Bean
Supplier<String> produce() {
    return () -> {
        String msg = "a message to produce";
        LOG.info("Producing message: " + msg);
        return msg;
    };
}

According to the binding naming conventions, the name of the binding will be produce-out-0. I can see that the message is indeed sent to service-bus-q-a (I have a consumer on the other side).

EDIT AND SOLUTION:

So it appears I had a problem with my environment, and after rebuilding it everything worked as expected and as Garry Russell's answer shows. Sorry for the time wasted. For posterity, this is exactly what worked for me:

When declaring a binding

spring:
  cloud:
    stream:
      bindings:
        produce-out-0:
          destination: service-bus-q-a
          producer:
            error-channel-enabled: true

The error channel that will be created will be named {destination}.errors, in this case service-bus-q-a.errors. In addition you have the global error channel errorChannel that will also be called if an error occurs. So you can use either

@ServiceActivator(inputChannel = "service-bus-q-a.errors")
public void errors(ErrorMessage receiveMsg) {
    System.err.println("receive error msg: " + receiveMsg);
}

To receive the errors from service-bus-q-a or

@ServiceActivator(inputChannel = "errorChannel")
public void errors(ErrorMessage receiveMsg) {
    System.err.println("receive error msg: " + receiveMsg);
}

To receive the error from the global error channel.

1
It looks like they only recently added support for that: github.com/microsoft/spring-cloud-azure/commits/master/…. Oh - looks like that's only on the consumer side.Gary Russell
So there is no way to recover from producer send timeouts?apines
Sorry; I don't know; I am not familiar with that binder.Gary Russell
Do you know by any chance if there's a non-binder specific way to handle producer errors?apines
Hmmm - I just looked at their code and they do inject the errorChannel into the handler (github.com/microsoft/spring-cloud-azure/blob/…) so it should work if error-channel-enabled is true. Try using a debugger.Gary Russell

1 Answers

2
votes

I just tested it with this yaml and the property is true as expected.

spring:
  cloud:
    stream:
      bindings:
        output:
          producer:
            error-channel-enabled: true
    azure:
      servicebus:
        connectionString: Endpoint=sb://foo.bar

Are you sure your producer name (produce-out-0) is correct?