Exceptions in EventingBasicConsumer

370 views
Skip to first unread message

johndoe...@gmail.com

unread,
Feb 22, 2016, 5:03:07 PM2/22/16
to rabbitmq-users
Hi,

My basic workflow is this:
- message consumer reads message from queue
- event handler attempts to write to disk
- but disk is full, or perhaps no permission to write to disk
- I want to throw an exception from the event handler
  and have it bubble all the way up to the caller
- the caller, in my case, is a Windows Service
  and I want my Windows Service to decide what to do (- e.g. shut itself down)

The problem?
* I try to throw an exception in my EventHandler, but it doesn't get caught.

What's the appropriate behavior? Should EventHandlers be throwing exceptions? If not, how should I be handling and communicating these errors to the host/caller?
Thanks!

Here's a code snippet:

        public void StartConsumer(string queueName, CancellationToken token)
       
{
           
IConnection conn = this.GetConnection();

           
try
           
{
               
using (IModel channel = conn.CreateModel())
               
{

                    channel
.BasicRecoverOk += (x, eventArgs) =>
                         
this.HandleChannelBasicRecoverOk(channel, eventArgs, queueName, token);

                   
// create our consumer
                   
var consumer = new EventingBasicConsumer(channel);


                    consumer
.Received += (x, eventArgs) =>
                       
this.HandleConsumerReceived(channel, eventArgs, queueName, token, (EventingBasicConsumer)x);
                    consumer
.ConsumerCancelled += (x, eventArgs) =>
                       
this.HandleConsumerCancelled(channel, eventArgs, queueName, token, (EventingBasicConsumer)x);
                    consumer
.Shutdown += (x, eventArgs) =>
                       
this.HandleConsumerShutdown(channel, eventArgs, queueName, token, (EventingBasicConsumer) x);

                    channel
.BasicConsume(queue: queueName, noAck: false, consumer: consumer);

                   
// spin-wait
                   
while (!token.IsCancellationRequested)
                   
{
                       
Thread.Sleep(250);
                   
}
                   
if (token.IsCancellationRequested)
                   
{  
                       
if (channel.IsOpen)
                            channel
.BasicCancel(consumer.ConsumerTag);
                   
}
               
}
           
}
           
catch (Exception ex)
           
{
                _logService
.WriteError(ex);
               
throw;
           
}
       
}
       
private void HandleConsumerReceived(IModel channel, BasicDeliverEventArgs eventArgs,
               
string queueName, CancellationToken token, EventingBasicConsumer consumer)
       
{
           
try
           
{
               
string message = System.Text.Encoding.UTF8.GetString(eventArgs.Body);
                _myMessageProcessor
.Run(message)
           
}
           
catch (Exception ex)
           
{  
                channel
.BasicNack(deliveryTag: eventArgs.DeliveryTag, multiple: false, requeue: true);
               
throw new MyCustomException("Message Processor threw an unexpected exception", ex);
           
}
       
}





Michael Klishin

unread,
Feb 23, 2016, 12:56:42 AM2/23/16
to rabbitm...@googlegroups.com, johndoe...@gmail.com
On 23 February 2016 at 01:03:10, johndoe...@gmail.com (johndoe...@gmail.com) wrote:
> The problem?
> * I try to throw an exception in my EventHandler, but it doesn't
> get caught.
>
> What's the appropriate behavior? Should EventHandlers be throwing
> exceptions?

RabbitMQ event handlers are regular C# event handlers, there is nothing special about them.
I’d expect the handlers to handle their exceptions.

We have an issue for uncaught exceptions, although it is supposed to mimic what the Java
client has, where eventing consumer doesn’t exist ;)

https://github.com/rabbitmq/rabbitmq-dotnet-client/issues/132 
--
MK

Staff Software Engineer, Pivotal/RabbitMQ


Reply all
Reply to author
Forward
0 new messages