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

时间:2013-07-08 13:03:09

标签: wcf workflow-foundation-4

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

  1. 我看到一些错误只触发 ProvideFault ,但从未发生过HandleError,其中一个例子是:

    System.NullReferenceException:未将对象引用设置为对象的实例。 在System.ServiceModel.Activities.Dispatcher.DurableInstanceManager.GetInstanceAsyncResult.GetInstance() 在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 timeout)

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

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

  5. 所以我的结论是,要记录所有错误,我必须登录这两种方法。但由于3 ..

    ,这会导致大量重复的日志条目

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

    有没有更好,更可靠的方法来记录WF服务中可能发生的所有错误?

    请不要指向Logging exceptions in WCF with IErrorHandler inside HandleError or ProvideFault?,因为它没有提供任何帮助。

1 个答案:

答案 0 :(得分:0)

我已经看到场景2发生在不同的上下文(BizTalk适配器)中,并且似乎调用了HandleError,因为适配器中发生了异常,但是{{1是被调用,因为没有实际返回的消息 - 故障以这样的方式发生,即它阻止适配器实际生成/读取/翻译消息并将其传递给管道。这似乎排除了即使生成错误消息也是如此。无法从管道读取似乎构成了这一点 - 您的服务并不知道它是否因为远程服务器发生故障而无法连接或失败而失败。 ProvideFault之类的内容也可能导致此问题,或者(在我的特定情况下)TransactionAbortedException可能导致此问题。

这应该为案例#1提供一些线索,我自己还没有看到或转载过:它是由于消息链中某处的异常处理不当造成的。在这种情况下,生成了一条错误消息,但链上方的某些内容未能以可以调用SqlException的方式处理异常。 HandleError在这里有意义 - 如果你没有正确处理空检查,很难说在这种情况下会发生什么其他事情。

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