This sample shows how, based on the exception type, a message can be either retried, sent to the error queue, or ignored. The portable Particular Service Platform will list the messages arriving in the error queue.
In Versions 6 and above, the IManageMessageFailures
is deprecated and there's no direct way to manage custom exceptions. The Recoverability API allows for much easier configuration of immediate and delayed retries. However finer-grain control can be achieved by writing a custom Behavior and having it executed as step in the message handling pipeline.
public override async Task Invoke(ITransportReceiveContext context, Func<Task> next)
{
try
{
await next()
.ConfigureAwait(false);
}
catch (MyCustomException)
{
// Ignore the exception, avoid doing this in a production code base
Log.WarnFormat("MyCustomException was thrown. Ignoring the error for message Id {0}.", context.Message.MessageId);
}
catch (MessageDeserializationException deserializationException)
{
// Custom processing that needs to occur when a serialization failure occurs.
Log.Error("Message deserialization failed", deserializationException);
throw;
}
catch (Exception ex)
{
//Throwing will eventually send the message to the error queue
Log.Error("Message failed.", ex);
throw;
}
}
To register the new exception handler:
var pipeline = endpointConfiguration.Pipeline;
pipeline.Register(
behavior: new CustomErrorHandlingBehavior(),
description: "Manages thrown exceptions instead of delayed retries.");
Beware of swallowing exceptions though, since it is almost never intended and the message will be removed from the queue, as if it has been processed successfully.