#rebus
Вопрос:
Я знаю, что ребус хранит ошибки при доставке сообщений в IErrorTraker (InMemErrorTracker). Есть ли какой-либо способ ввести IErrorTraker в обработчики или другой способ получить исключение из предыдущей попытки? Спасибо!
Ответ №1:
Да, есть, но вам нужно будет немного поработать самому.
Как вы правильно поняли, IErrorTracker
это то, что Ребус использует для отслеживания неудачных попыток доставки, и поэтому он сможет предоставлять информацию о ранее зарегистрированных исключениях, учитывая идентификатор обрабатываемого сообщения.
Однако это внутреннее для Ребуса, поэтому оно никоим образом не раскрывается. Однако вы можете получить его несколькими различными способами, например, включив шаг входящего конвейера в контекст входящего шага:
Способ сделать это (в грубом и неискушенном виде) можно увидеть здесь:
Configure.With(activator)
.Transport(t => (...))
.Options(o => o.Decorate<IPipeline>(c =>
{
var pipeline = c.Get<IPipeline>();
var errorTracker = c.Get<IErrorTracker>();
var step = new ExposeErrorTrackerStep(errorTracker);
return new PipelineStepConcatenator(pipeline)
.OnReceive(step, PipelineAbsolutePosition.Front);
}))
.Start();
где более сложная версия поместила бы уродливые элементы конфигурации в соответствующий метод расширения:
public static void ExposeErrorTracker(this OptionsConfigurer configurer) =>
configurer.Decorate<IPipeline>(c =>
{
var pipeline = c.Get<IPipeline>();
var errorTracker = c.Get<IErrorTracker>();
var step = new ExposeErrorTrackerStep(errorTracker);
return new PipelineStepConcatenator(pipeline)
.OnReceive(step, PipelineAbsolutePosition.Front);
});
а затем используйте это вот так:
Configure.With(activator)
.Transport(t => (...))
.Options(o => o.ExposeErrorTracker())
.Start();
Наконец, вот реализация этого шага:
[StepDocumentation("Makes Rebus' IErrorTracker available in the incoming step context.")]
class ExposeErrorTrackerStep : IIncomingStep
{
readonly IErrorTracker _errorTracker;
public ExposeErrorTrackerStep(IErrorTracker errorTracker) => _errorTracker = errorTracker;
public Task Process(IncomingStepContext context, Func<Task> next)
{
context.Save(_errorTracker);
return next();
}
}
Как вы можете видеть, он просто спрятал IErrorTracker
контекст входящего шага, к которому вы можете получить доступ IMessageContext
, который автоматически настраивается для ввода в обработчики.
Полный рабочий пример можно посмотреть здесь: https://github.com/rebus-org/Rebus/blob/master/Rebus.Тесты/Примеры/ExposeInternalService_ErrorTracker.cs