-
Notifications
You must be signed in to change notification settings - Fork 0
Automatic retries and error handling
When Rebus receives a message, it keeps the message's ID in an in-memory dictionary along with a few pieces of information on when the message was received, etc.
It also keeps track of how many times it has seen the message before!
Also, Rebus will always receive the message inside of a TransactionScope
(an "ambient transaction"), which ensures that the message will return to the queue if something fails when handling it.
This way, Rebus can see if message delivery has failed a certain number of times (default: 5), and if the same message is received one more time, it will be considered "poisonous", and it will be forwarded to Rebus' error queue.
This way, the message is persisted to be retried at a later time.
Either you turn to Rebus' log - a full exception will be logged at the WARN level for each delivery attempt, except the last which will be logged as an ERROR.
Moreover, to make it even easier, the full exceptions will also be included in a header inside the message, allowing Rebus Snoop to show you what went wrong.
With Rebus, it is assumed that you want to retry delivery when it fails - and by default, it will be delivered 5 times before the message is moved to the error queue.
You can configure the default though - just set the maxRetries
attribute on the rebus
element in your app.config, e.g. like this configuration sample where the number of delivery attempts is increased to 10:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="rebus" type="Rebus.Configuration.RebusConfigurationSection, Rebus" />
</configSections>
<rebus inputQueue="some.input.queue"
errorQueue="error"
workers="1"
maxRetries="10"/>
</configuration>
Furthermore, you can customize the number of retries for specific exception types - e.g. like so:
Configure.With(...)
.(...)
.Behavior(b =>
{
b.SetMaxRetriesFor<Raven.Abstractions.Exceptions.ConcurrencyException>(10);
b.SetMaxRetriesFor<System.ApplicationException>(0);
})
to increase the chance of overcoming transient exceptions that are prone to happen often and decrease the chance of clogging the input queue with a message that leads to something that can most likely not be overcome.
If you configure Rebus to retry messages many times, the in-memory list of exception details could grow quite large, effectively generating the symptoms of a memory leak. Therefore, Rebus will keep at most 10 pieces of full exception details around, trimming the list of the oldest whenever a new one arrives.