NServiceBus 6:想要一些错误忽略错误队列

NServiceBus 6: want some errors to ignore eror queue

根据 Customizing Error Handling "Throwing the exception in the catch block will forward the message to the error queue. If that's not desired, remove the throw from the catch block to indicate that the message has been successfully processed." 这对我来说不是真的,即使我只是在行为中吞下任何类型的异常:

public override async Task Invoke(IInvokeHandlerContext context, Func<Task> next)
{
    try
    {
        await next().ConfigureAwait(false);
    }
    catch (Exception ex)
    {
    }
}

我在那里放置了一个断点并确保执行命中了 catch 块。然而,在恐吓和延迟重试之后,消息不可避免地会出现在错误队列中。除了这个之外,我没有更多的行为在管道中。

只有当我在 catch 块中 运行 context.DoNotContinueDispatchingCurrentMessageToHandlers(); 时,它才会阻止将错误发送到错误队列,但它也会阻止任何进一步的立即和延迟重试。

非常感谢任何关于它为何违反特定 NserviceBus 文档的想法

NserviceBus 版本。使用:6.4.3

更新:

我只希望某些类型的异常不被发送到 NServiceBus 6 中的错误队列,但是为了使测试用例更清晰并缩小问题的根本原因,我只使用类型异常。抛出异常后,执行肯定会命中空的 catch 块。这是更多代码:

public class EndpointConfig : IConfigureThisEndpoint
{
    public void Customize(EndpointConfiguration endpointConfiguration)
    {

     endpointConfiguration.DefineEndpointName("testEndpoint");
     endpointConfiguration.UseSerialization<XmlSerializer>();
     endpointConfiguration.DisableFeature<AutoSubscribe>();
     configure
            .Conventions()
            .DefiningCommandsAs(t => t.IsMatched("Command"))
            .DefiningEventsAs(t => t.IsMatched("Event"))
            .DefiningMessagesAs(t => t.IsMatched("Message"));
     var transport = endpointConfiguration.UseTransport<MsmqTransport>();


     var routing = transport.Routing();
     var rountingConfigurator = container.GetInstance<IRountingConfiguration>();
     rountingConfigurator.ApplyRountingConfig(routing);
     var instanceMappingFile = routing.InstanceMappingFile();
     instanceMappingFile.FilePath("routing.xml");

     transport.Transactions(TransportTransactionMode.TransactionScope);

     endpointConfiguration.Pipeline.Register(
                    new CustomFaultMechanismBehavior(),
                    "Behavior to add custom handling logic for certain type of exceptions");

     endpointConfiguration.UseContainer<StructureMapBuilder>(c => c.ExistingContainer(container));

     var recoverability = endpointConfiguration.Recoverability();

     recoverability.Immediate(immediate => 
                {
                    immediate.NumberOfRetries(2);
                });

     endpointConfiguration.LimitMessageProcessingConcurrencyTo(16);

     recoverability.Delayed(delayed =>
        {
                    delayed.NumberOfRetries(2);
        });

     endpointConfiguration.SendFailedMessagesTo("errorQueue");
    ...
    }
}

public class CustomFaultMechanismBehavior : Behavior<IInvokeHandlerContext>
{
    public override async Task Invoke(IInvokeHandlerContext context, Func<Task> next)
    {
        try
        {
            await next().ConfigureAwait(false);
        }
        catch (Exception ex)
        {               
        }
    }
}

更新 2 我想我知道发生了什么:消息由第一个处理程序处理,该处理程序抛出一个被 Behavior catch 块捕获的异常,但随后 NServiceBus 运行time 尝试实例化第二个处理程序 class 这也是应该的处理消息(它处理 class 消息的来源)。那是在依赖 class 之一的构造函数中抛出另一个异常的地方。 StructureMap 尝试将处理程序及其在构造函​​数和进程 运行 中声明的所有依赖服务实例化到异常中。而且这个异常没有被CustomFaultMechanismBehavior捕捉到。

所以我现在重新表述我的问题:有什么方法可以抑制在构造函数内部或仅在 StructureMap classes 初始化期间发生的错误(忽略错误队列)?似乎描述的方式没有涵盖这种情况

您的行为在处理程序调用时被激活。这意味着您正在捕获 Handle 方法内部发生的异常,因此任何其他异常,例如在处理程序的构造函数中不会被捕获。

要更改 'capture' 异常的方式,您可以更改行为的激活方式,例如将其从 Behavior<IInvokeHandlerContext> 更改为 Behavior<ITransportReceiveContext>,当传输收到消息时激活。您可以调查不同的阶段和行为,看看哪一个最适合您的目的。