Hi,
I have a question when using the interface IConsumer<Fault<T>> to handle the exception messages. Below is my code snippet:
public class UpdateInventoryConsumer : IConsumer<UpdateInventory>
{
public async Task Consume(ConsumeContext<UpdateInventory> context)
{
if (Math.Abs(context.Message.Qty) > 100)
throw new Exception("The limit Qty is great than abs(100)");
await Console.Out.WriteLineAsync($"Updating Inventory-> Qty:{context.Message.Qty} to {context.Message.Location}-{context.Message.ProductId} When {context.Message.Timestamp}");
}
}
public class UpdateInventoryFaultConsumer : IConsumer<Fault<UpdateInventoryConsumer>>
{
private readonly ILog _log = Logger.Get<UpdateInventoryFaultConsumer>();
public async Task Consume(ConsumeContext<Fault<UpdateInventoryConsumer>> context)
{
var originalMessage = context.Message.Message;
var exceptions = context.Message.Exceptions;
Array.ForEach(exceptions, ex => _log.Info($"received exception:{ex.Message}"));
await Console.Out.WriteLineAsync($"discarding message:{JsonConvert.SerializeObject(originalMessage)}");
}
}
I handle the exceptions using the method e.Consumer<T>() with Fault<T>class(UpdateInventoryFaultConsumer).but it is not running when fault message comming. So using the newest Masstransit, how can I consume fault message?
public bool Start(HostControl hostControl)
{
_log.Info("Creating bus...");
_busControl = Bus.Factory.CreateUsingRabbitMq(x =>
{
IRabbitMqHost host = BusInitializer.CreateRabbitMqHost(x);
x.ReceiveEndpoint(host, "Samples.TestQueue", e =>
{
e.UseRetry(Retry.Immediate(5));
e.Consumer<UpdateInventoryConsumer>();
e.Consumer<UpdateInventoryFaultConsumer>();
});
});
_log.Info("Starting bus...");
_busControl.Start();
return true;
}
The _Fault_ is with the message, not the consumer. So change your second method to include:
public class UpdateInventoryFaultConsumer :
IConsumer<Fault<UpdateInventory>>
{
private readonly ILog _log = Logger.Get<UpdateInventoryFaultConsumer>();
public async Task Consume(ConsumeContext<Fault<UpdateInventory>> context)
{
var originalMessage = context.Message.Message;
var exceptions = context.Message.Exceptions;
Array.ForEach(exceptions, ex => _log.Info($"received exception:{ex.Message}"));
await Console.Out.WriteLineAsync($"discarding message:{JsonConvert.SerializeObject(originalMessage)}");
}
}
@phatboyg
Thanks so much it works. When fault message handled,it moved to the queue "_error_skipped"
_error_skipped queue should not be created its wrong
@phatboyg What if I need other specific exception parameters? For example, if the Exception is a FaultException
Thanks in advance,
Eduardo Monteiro de Barros
Most helpful comment
The _Fault_ is with the message, not the consumer. So change your second method to include: