1

I'd like to give error queues names in EasyNetQ based on the name of the queue that originated the error. For example, all faulted messages from QueueA would go to QueueA.Error; QueueB messages would be redirected to QueueB.Error, and so on.

However, the ErrorQueueNamingConvention doesn't receive a MessageReceivedInfo parameter, as ErrorExchangeNamingConvention does, and so I cannot know what is the name of the original queue. Is there any way of getting it or any workarounds?

Thanks

peflorencio
  • 2,284
  • 2
  • 32
  • 40

1 Answers1

2

You can do this by setting the ErrorQueueNamingConvention on the IBus. So it's done at the bus level, not the individual message level. I name my error queues to match the queue to which the consumer is bound (which I define in configuration). When errors occur while processing messages from queue A, for example, those errors will be routed to queue A_Errors. Here's a sample:

                var errorExchangeName = _configuration.ExchangeName + "_Errors";
                var errorQueueName = _configuration.ListenerQueueName + "_Errors";

                var conventions = _bus.Advanced.Container.Resolve<IConventions>();
                conventions.ErrorExchangeNamingConvention = info => errorExchangeName;
                conventions.ErrorQueueNamingConvention = () => errorQueueName;  

You can see in the following code fragment from https://github.com/EasyNetQ/EasyNetQ/blob/master/Source/EasyNetQ/Consumer/DefaultConsumerErrorStrategy.cs how EasyNetQ uses your ErrorQueueNamingConvention to bind to the error queue so it can forward messages to it:

private string DeclareErrorExchangeAndBindToDefaultErrorQueue(IModel model, ConsumerExecutionContext context)
        {
            var originalRoutingKey = context.Info.RoutingKey;

            return errorExchanges.GetOrAdd(originalRoutingKey, _ =>
            {
                var exchangeName = conventions.ErrorExchangeNamingConvention(context.Info);
                model.ExchangeDeclare(exchangeName, ExchangeType.Direct, durable: true);
                model.QueueBind(conventions.ErrorQueueNamingConvention(), exchangeName, originalRoutingKey);
                return exchangeName;
            });
        }

So, if you need even more control then you can override this DefaultConsumerErrorStrategy as well. There you can get at the context you are looking for, though I don't think you need it to get the behavior you are looking for.

Also see this answer.

Community
  • 1
  • 1
BitMask777
  • 2,543
  • 26
  • 36