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

时间:2018-02-27 19:15:35

标签: nservicebus

根据a call to S3's REST API"在catch块中抛出异常会将消息转发到错误队列。如果不需要,请从catch块中删除throw以指示消息已成功处理。"即使我只是在行为中吞下任何类型的异常,这对我来说也是如此:

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

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

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

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

NserviceBus ver。使用:6.4.3

更新

我只希望某些类型的异常不被发送到NServiceBus 6中的错误队列,但是为了使测试用例更加清晰并缩小问题的根本原因我只使用类型Exception。抛出异常后,执行肯定会遇到空的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 我想我知道发生了什么:消息由第一个处理程序处理,该处理程序抛出一个由行为捕获块捕获的异常,但随后NServiceBus运行时尝试实例化第二个处理程序类,它也应该处理消息(它处理消息派生的类)。那是在一个依赖类的构造函数中抛出另一个异常的地方。 StructureMap尝试实例化处理程序,并在构造函数和进程中声明的所有依赖服务都会遇到异常。并且CustomFaultMechanismBehavior没有捕获此异常。

所以我现在重新提出我的问题:有没有办法在构造函数内部或者只是在StructureMap类初始化期间抑制错误(忽略错误队列)?似乎所描述的方式不包括这种情况

1 个答案:

答案 0 :(得分:2)

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

要更改“捕获”例外的方式,您可以更改行为的激活方式,例如:将其从Behavior<IInvokeHandlerContext>更改为Behavior<ITransportReceiveContext>,这会在传输接收消息时激活。您可以调查不同的阶段和行为,以确定哪一个最适合您的目的。