question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support NACK on exceptions

See original GitHub issue

It’s crucial to me to nack a message if I didn’t handle it. Currently if my application crashes the message just dissapears. I have read the documentation that says

If your subscription callback throws an exception, EasyNetQ will take the message that was being consumed and wrap it in a special error message. The error message will be published to the EasyNetQ error queue (named EasyNetQ_Default_Error_Queue). You should monitor the error queue for any messages. The error message includes all the information necessary to re-publish the original message as well as the exception’s type, message and stack trace. You can use the EasyNetQ.Hosepipe utility to re-publish error messages. See the section on EasyNetQ.Hosepipe below.

But shouldn’t it be default? It’s suprising to me that I have to create yet another queue and republish messages manually when it’s simply shouldn’t be ack’ed.

My problem is that I must preserve messages order. If some message throws an exception then the whole queue should wait until this message gets processed. But it’s not possible if exception just makes this message to go into another queue.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:11 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
Pzixelcommented, May 31, 2018

Sorry for late response, I have suddenly been burrowed under tons of others tasks.

I have been tested following code:

using System;
using System.Threading.Tasks;
using EasyNetQ;
using EasyNetQ.Consumer;
using static System.Console;

namespace Console
{
    public static class Program
    {
        public static void Main()
        {
            Task.Run(async () =>
            {
                using (var bus = RabbitHutch
                                 .CreateBus(
                                     "host=myhost:5672;username=reader;password=mypass;requestedHeartbeat=20;prefetchcount=20;timeout=1000;publisherConfirms=true",
                                     x => x.Register<IConsumerErrorStrategy>(_ => new AlwaysRequeueErrorStrategy())
                                 ).Advanced)
                {
                    using (var _ = await ConsumeBus(bus, "blockchain", async () =>
                    {
                        WriteLine("Got new message");
                        throw new Exception();
                    }))
                    {
                        WriteLine("Listening for messages. Hit <return> to quit.");

                        ReadKey();
                    }
                }
            }).Wait();
        }

        private static async Task<IDisposable> ConsumeBus(IAdvancedBus bus, string queueName,
                                                          Func<Task> messageConsumptionTask)
        {
            var queue = await bus.QueueDeclareAsync(queueName, true).ConfigureAwait(false);
            return bus.Consume(queue,
                               (body, properties, info) =>
                                   messageConsumptionTask());
        }
    }

    public sealed class AlwaysRequeueErrorStrategy : IConsumerErrorStrategy
    {
        public void Dispose()
        {
        }

        public AckStrategy HandleConsumerError(ConsumerExecutionContext context, Exception exception)
        {
            return AckStrategies.NackWithRequeue;
        }

        public AckStrategy HandleConsumerCancelled(ConsumerExecutionContext context)
        {
            return AckStrategies.NackWithRequeue;
        }
    }
}

And it worked as expected.

Thank you, it really solves the problem. All bad messages stays in the queue and are requested a bit later

2reactions
Pzixelcommented, May 25, 2018

And still it works as expected. What versions of EasyNetQ and RabbitMQ are you using?

3.0.0 and 3.7.5 respectively.

Well, it’s a friday, and I have to go. Let’s continue our great talk at monday. I wish you a happy weekend.

Read more comments on GitHub >

github_iconTop Results From Across the Web

What's the correct exception type to NACK a message ...
I'm using spring boot with spring-amqp and annotation based listener to consume message from a rabbitmq broker. I've a spring component which ...
Read more >
Support Exceptions - Karen Ann Ulmer, P.C.
Examples of appropriate exceptions would include claims that the incomes and/or expenses were not correctly calculated, special circumstances ...
Read more >
Support Exceptions - Fifth Judicial District of Pennsylvania
To file Exceptions to a Support Hearing Officer's Recommendation. 20 DAYS TO FILE EXCEPTIONS: You have 20 days from the date of the...
Read more >
Where would you handle exceptions: controller, service ...
It will first go to the controller, assuming no middleware in place, service, repository if any and back to the controller. But what...
Read more >
Best Practices for exceptions - .NET
Learn best practices for exceptions, such as using try/catch/finally, handling common conditions without exceptions, and using predefined .
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found