NServiceBus обработка ошибок

Я понимаю, что пусть NServiceBus обрабатывает ошибку и позволяет ему повторить попытку или использовать второй уровень повторных попыток. Это допустимо для некоторой неизвестной ошибки в приложении.

Например, допустим, что значение транзакции == null, тогда я не хочу просто генерировать исключение и позволить шине NService обрабатывать его, так как я знаю, что это никогда не пройдет при каких-либо дополнительных попытках. Для известных сценариев исключений, что лучше всего это сделать?

Я использую саги, которые называют различные конечные точки (A,B,C,D). как вы справляетесь с вышеописанным сценарием ошибки в этих конечных точках, так как я не хочу, чтобы моя сага находилась в состоянии зависания.

1 ответ

Решение

Если у вас есть исключение (или класс исключений), о котором вы знаете, что никакое количество повторных попыток не поможет, то вы правы, лучше быстро потерпеть неудачу.

допустим, у вас есть такой обработчик

public void Handle(BadMath message)
{
   var zero = 0;
   var crash =  5 / zero;
   var msg = "I will never be reached...";

   this.SendReply(msg );
}

И вы хотите ловить и терпеть неудачу быстро для Div/0...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NServiceBus;
using NServiceBus.Features;
using NServiceBus.SecondLevelRetries.Helpers;

namespace My.Namespace.Messaging.Handlers
{
    public class ChangeRetryPolicy : INeedInitialization
    {
        public void Init()
        {
            Configure.Features.Disable<SecondLevelRetries>();

            Configure.Features.SecondLevelRetries(s => s.CustomRetryPolicy((tm) => 
            {
                // retry max 3 times
                if (TransportMessageHelpers.GetNumberOfRetries(tm) >= 3)
                {
                    // To send back a value less than zero tells the SecondLevelRetry
                    // satellite not to retry this message anymore. 
                    return TimeSpan.MinValue;
                }

                if (tm.Headers["NServiceBus.ExceptionInfo.ExceptionType"] == typeof(System.DivideByZeroException).FullName)
                {
                    return TimeSpan.MinValue;
                }  
                return TimeSpan.FromSeconds(5);
            }));

            Configure.Features
        }
    }

}

Если вы попытаетесь запустить обработчик с помощью модульного теста, тест, конечно, взорвется и выдаст ошибку. Если вы установите точку останова в обработчике на "crash = 5 / zero", а затем повторно запустите ваш проект, вы должны увидеть, что, когда NServiceBus пытается повторно доставить сообщение, повторные попытки второго уровня не происходят, а ваши недоставленные отправляются непосредственно в очередь ошибок.

Другие вопросы по тегам