根据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类初始化期间抑制错误(忽略错误队列)?似乎所描述的方式不包括这种情况
答案 0 :(得分:2)
您的行为在Handler调用时激活。这意味着您正在捕捉Handle
方法中发生的异常,因此任何其他异常,例如在处理程序的构造函数中将不会被捕获。
要更改“捕获”例外的方式,您可以更改行为的激活方式,例如:将其从Behavior<IInvokeHandlerContext>
更改为Behavior<ITransportReceiveContext>
,这会在传输接收消息时激活。您可以调查不同的阶段和行为,以确定哪一个最适合您的目的。