Reputation: 27803
We are currently using self-hosted NServiceBus to handle queuable messages in our system. Right now there are instances where a queued message might fail on the first try and work on the automatic retries.
Right now we are logging on all failures, but we really don't care (at least for alerts) if a message failed the first time but worked on a re-try. What we do want to get alerted to is if all retries failed and a message goes into the error queue.
Is there any way native to NServiceBus to have code run when it's moving a message to the error queue?
Upvotes: 2
Views: 586
Reputation: 18615
If you are using the rest of the Service Platform (and you should!) that means that your error queue will have ServiceControl sitting on top of it, reading messages out of error and audit and persisting the details to its database so that it can serve up that information via its REST API to ServicePulse (for monitoring system health and uptime) and ServiceInsight (for exploration and debugging.)
Assuming you are using ServiceControl, it's pretty easy to have an endpoint subscribe to MessageFailed events that are published by ServiceControl. I explained how to do it in my blog post Failed Message Notification with ServiceControl.
This way, each endpoint doesn't have to be responsible for this task, and it is accomplished asynchronously by a centralized error monitoring endpoint.
Upvotes: 2
Reputation: 27803
It appears the correct way to do this is to create a custom implementation of IManageMessageFailures
and registering the custom fault manager curing configuration time.
An example of this is:
public class CustomFaultManager : IManageMessageFailures
{
private readonly IManageMessageFailures faultManager;
static CustomFaultManager()
{
Configure.Instance.MessageForwardingInCaseOfFault();
}
public CustomFaultManager()
{
faultManager = new FaultManager();
((FaultManager)faultManager).ErrorQueue = ConfigureFaultsForwarder.ErrorQueue;
}
void IManageMessageFailures.SerializationFailedForMessage(TransportMessage message, Exception e)
{
faultManager.SerializationFailedForMessage(message, e);
}
void IManageMessageFailures.ProcessingAlwaysFailsForMessage(TransportMessage message, Exception e)
{
faultManager.ProcessingAlwaysFailsForMessage(message, e);
//Custom code goes here
}
void IManageMessageFailures.Init(Address address)
{
faultManager.Init(address);
}
}
from https://github.com/Particular/NServiceBus/issues/463
Upvotes: 1