我有一个有趣的用例,其中某些异常类型表示“此消息不再有效且应该被忽略”,但此代码对Bus
没有任何意识,以便调用{{1} }。
我讨厌像每个消息处理程序中都需要的try / catch块这样的样板代码。所以我开始实现一个UnitOfWork来处理和吞下异常,但我找不到告诉框架的方法“是的,这个代码生成了一个异常,但忘记了这一点并完成了事务。”
Bus.DoNotContinueDispatchingCurrentMessageToHandlers()
不起作用。我尝试注入Bus.DoNotContinueDispatchingCurrentMessageToHandlers()
并调用ITransport
,但这导致整个宇宙爆炸。即使单步执行源代码,我似乎也不知所措。
请注意,很可能这是一个可怕的想法,因为假设实际上存在异常情况时没有异常将导致事务提交,导致谁知道有多少不明的未知副作用。因此,最好有一个方法仍然回滚事务但丢弃该消息。但我会对潜在的“是的我知道我在做什么,提交交易而不管异常”选项感兴趣。
答案 0 :(得分:5)
从NServiceBus版本4.4开始,您可以通过在我们的处理程序管道中注入一个行为来控制它。
这让你控制哪些例外可以静音。
class MyExceptionFilteringBehavior : IBehavior<HandlerInvocationContext>
{
public void Invoke(HandlerInvocationContext context, Action next)
{
try
{
//invoke the handler/rest of the pipeline
next();
}
//catch specific exceptions or
catch (Exception ex)
{
//modify this to your liking
if (ex.Message == "Lets filter on this text")
return;
throw;
}
}
有几个样本如何运作:
http://docs.particular.net/samples/pipeline/
那就是说我完全同意拉蒙的观点,只有当你不能改变设计以避免这种情况时才应该使用这个技巧。
答案 1 :(得分:1)
一个肮脏的解决方案是让一个工作单元测试异常,将消息id放在一个共享&#39;忽略&#39; bag(内存中的并发字典,db,什么对你有用),让它失败以便一切都回滚,在重试时有一个通用的消息处理程序比较消息ID并让那个调用Bus.DoNotContinueDispatchingCurrentMessageToHandlers()
如果您不想使用某个工作单元,那么您可以尝试使用AppDomain.FirstChanceException。
我不会建议任何这些作为好的解决方案: - )
答案 2 :(得分:0)
你为什么要吞下&#39;未处理的例外?
如果你想忽略一个异常,那么你应该在处理程序中捕获这些异常,然后返回并记录它。
我更感兴趣的是国家呢?你可能已经写过商店了。不应该回滚这些写入吗?如果你吞下一个例外事务提交。
在我看来,你正在运行一种“至少一次交付”的方式。环境。那么你需要在某处存储某种消息ID。
或者这是一个基于陈旧状态的几个演员发起的行动?在这种情况下,您需要具有第一个/最后一个写入获胜结构,它只是忽略基于陈旧项目的命令。
如果您处理事件,则吞下异常似乎不正确。他们通常说你可以忽略命令,但你总是要处理事件。
这不应该是验证的一部分吗?如果验证命令,则可以决定忽略它。