Error handling

NServiceBus has a built-in exception catching and handling logic, which encompasses all calls to the user code. When an exception bubbles through to the NServiceBus infrastructure, it rolls back the transaction on the transactional endpoint. The message is then returned to the queue, and any messages that the user code tried to send or publish won't be sent out.

Configure the error queue

When a message fails NServiceBus automatically retries the message. On repeated failure NServiceBus forwards that message to a designated error queue.

When running with transport transactions disabled NServiceBus will perform a best-effort error message forwarding, i.e. if moving to the error queue fails, the message will be lost.WARNING: When running with transport transactions disabled. Both FLR and SLR will be silently disabled when transactions are turned off.

Error queue can be configured in several ways.

Using Code

6-pre NServiceBus
endpointConfiguration.SendFailedMessagesTo("targetErrorQueue");

Using a IConfigurationProvider

6-pre NServiceBus
class ProvideConfiguration : IProvideConfiguration<MessageForwardingInCaseOfFaultConfig>
{
    public MessageForwardingInCaseOfFaultConfig GetConfiguration()
    {
        return new MessageForwardingInCaseOfFaultConfig
        {
            ErrorQueue = "error"
        };
    }
}
4.x - 5.x NServiceBus
class ProvideConfiguration : IProvideConfiguration<MessageForwardingInCaseOfFaultConfig>
{
    public MessageForwardingInCaseOfFaultConfig GetConfiguration()
    {
        return new MessageForwardingInCaseOfFaultConfig
        {
            ErrorQueue = "error"
        };
    }
}

Using a ConfigurationSource

6-pre NServiceBus
public class ConfigurationSource : IConfigurationSource
{
    public T GetConfiguration<T>() where T : class, new()
    {
        if (typeof(T) == typeof(MessageForwardingInCaseOfFaultConfig))
        {
            MessageForwardingInCaseOfFaultConfig errorConfig = new MessageForwardingInCaseOfFaultConfig
            {
                ErrorQueue = "error"
            };

            return errorConfig as T;
        }

        // To in app.config for other sections not defined in this method, otherwise return null.
        return ConfigurationManager.GetSection(typeof(T).Name) as T;
    }
}
public class ConfigurationSource : IConfigurationSource
{
    public T GetConfiguration<T>() where T : class, new()
    {
        if (typeof(T) == typeof(MessageForwardingInCaseOfFaultConfig))
        {
            MessageForwardingInCaseOfFaultConfig errorConfig = new MessageForwardingInCaseOfFaultConfig
            {
                ErrorQueue = "error"
            };

            return errorConfig as T;
        }

        // To in app.config for other sections not defined in this method, otherwise return null.
        return ConfigurationManager.GetSection(typeof(T).Name) as T;
    }
}

Then at configuration time:

6-pre NServiceBus
endpointConfiguration.CustomConfigurationSource(new ConfigurationSource());
5.x NServiceBus
busConfiguration.CustomConfigurationSource(new ConfigurationSource());
3.x - 4.x NServiceBus
configure.CustomConfigurationSource(new ConfigurationSource());

Using App.Config

6-pre NServiceBus
<configuration>
  <configSections>
    <section name="MessageForwardingInCaseOfFaultConfig" 
             type="NServiceBus.Config.MessageForwardingInCaseOfFaultConfig, NServiceBus.Core" />
  </configSections>
  <MessageForwardingInCaseOfFaultConfig ErrorQueue="error@adminMachine"/>
</configuration>
<configuration>
  <configSections>
    <section name="MessageForwardingInCaseOfFaultConfig" 
             type="NServiceBus.Config.MessageForwardingInCaseOfFaultConfig, NServiceBus.Core" />
  </configSections>
  <MessageForwardingInCaseOfFaultConfig ErrorQueue="error@adminMachine"/>
</configuration>
In NServiceBus Version 3.x the ErrorQueue settings can be set both via the MessageForwardingInCaseOfFaultConfig section and the MsmqTransportConfig section.

For more details on MsmqTransportConfig refer to the MSMQ transport article.

Error queue monitoring

Administrators should monitor the error queue, in order to detect when problems occur. The message in the error queue contains information regarding its source queue and machine. Having that information an administrator can investigate the specific node and solve the problem, e.g. bring up a database that went down.

Monitoring and handling of failed messages with ServicePulse provides access to full exception details (including stack-trace). ServiceInsight additionally enables advanced debugging with a full message context. Both of them provide a retry functionality to send the message back to the endpoint for re-processing. For more details, see Introduction to Failed Messages Monitoring in ServicePulse.

If either ServicePulse or ServiceInsight is not available in the environment, the retry operation can be performed using the native management tools of the selected transport:

ReturnToSourceQueue.exe

The MSMQ command line tool ReturnToSourceQueue has been deprecated and moved to ParticularLabs/MsmqReturnToSourceQueue.

Samples

  • Automatic Retries
    With SLR, the message causing the exception is instantly retried via a retries queue instead of an error queue.
  • Fault Tolerance
    Messaging approaches to help with failure scenarios.
  • Notifications
    Using the notifications API.
  • Stack Trace Cleaning
    Shows how to minimize the stack trace written to the Error queue and the log output.

Related Articles


Last modified 2016-04-21 11:40:04Z