HandleError与ProvideFault工作流服务不一致,如何处理?

Ach*_*him 8 wcf workflow-foundation-4

在我们的WF4工作流服务中,我们尽量保持健壮.我们做的一件事就是在HandleError和ProvideFault(IErrorhandler)中记录错误.文档清楚地说明HandleError是进行日志记录的正确位置,但我发现有些奇怪的事情发生了:

  1. 我看到一些错误只触发ProvideFault,但从来没有HandleError,一个例子是:

    System.NullReferenceException:未将对象引用设置为对象的实例.在System.ServiceModel.Activities.Dispatcher.DurableInstanceManager.GetInstanceAsyncResult.GetInstance()at System.ServiceModel.Activities.Dispatcher.DurableInstanceManager.GetInstanceAsyncResult..ctor

  2. 还有一些错误只触发HandleError,但从不提供ProvideFault,一个例子是:

    System.ServiceModel.CommunicationException:从管道读取错误:管道已结束.(109,0x6d).在System.ServiceModel.Channels.PipeConnection.Read(Byte []缓冲区,Int32偏移量,Int32大小,TimeSpan超时)处于System.ServiceModel.Channels.SessionConnectionReader.Receive(TimeSpan超时)

  3. 最后有错误触发两者,首先是ProvideFault,然后是HandleError(在后台线程上)

  4. 如果可能的话,我也想记录相应的传入消息.我使用OperationContext.Current.RequestContext.RequestMessage.ToString()执行此操作这通常只适用于ProvideFault,在HandleError中我们不再有RequestContext

所以我的结论是,要记录所有错误,我必须登录这两种方法.但由于3 ..这导致了大量重复的日志条目.

我目前的解决方法是"记住"来自ProvideFault的最后一个记录的异常,如果相同的异常进入HandleError则忽略它.看起来不是很干净.

有没有人能够更好,更可靠地记录WF服务中可能发生的所有错误?

请不要指向使用HandleError或ProvideFault中的IErrorHandler在WCF中记录异常?因为这没有提供任何帮助.

Dan*_*eld 0

我已经看到场景 2 发生在不同的上下文(BizTalk 适配器)中,似乎被HandleError调用是因为适配器中发生了异常,但ProvideFault没有调用,因为没有消息实际返回 - 错误发生在这样的情况下它阻止适配器实际生成/读取/翻译消息并将其传递到管道。这似乎甚至排除了生成故障消息的可能性。从管道读取失败似乎构成了这种情况 - 您的服务不知道它是否失败,因为它甚至从未连接过,或者是否因为远程服务器失败而失败。诸如此类的事情TransactionAbortedException也可能导致这种情况,或者(在我的特定情况下)可能SqlException导致这种情况。

这应该为案例 #1 提供一些线索,我自己没有见过或复制过该案例:这是由于消息链中某处的异常处理不当造成的。HandleError在这种情况下,生成了一条错误消息,但链上层的某些东西无法以可以调用的方式处理异常。ANullReferenceException在这里是有道理的 - 如果你没有正确处理空检查,那么很难说在这种情况下还会发生什么。

就解决这个问题而言,我可能会尝试在两个地方登录,并提供一些附加信息来解释日志的来源。即使它确实重复记录,这也是安全的。另一方面,如果您有一个生成这些场景中的一个或两个的异常列表,您可以实现逻辑来检查它是什么类型的异常(或它发生的位置) - 如果它是一个异常,则可能会减少日志记录可能会通过其他方法处理。