处理WCF异常/故障以及FaultException和IErrorHandler



我想为我的WCF应用程序实现一个适当的异常处理。在谷歌搜索了一下之后,我发现了两个解决方案。

  1. 为客户端提供FaultExceptions
  2. 使用IErrorHandler处理一般异常。
但是,我没有找到一个结合了这两种方法的实际示例——,如果这被认为是良好的实践

我的想法:

抛出带有自己详细类型的faultexception

throw new FaultException<StackOverflowFault>(
    new StackOverflowFault(StackOverflowFaultCode.Rules,
        "This question is not considered as constructive."));

IErrorHandler捕获未处理的异常并记录它们

public bool HandleError(Exception ex) {
    try {
        SomeLogger.Error(ex.Message, ex.Source);
        return true;
    } catch (Exception) {
        // Well, there was an exception handling the
        // exception :(
        // -> Drop the exception and throw a new one
        throw new Exception("Unknown exception occured.");
    }
}

…并根据异常类型

提供故障

(不是一切都是为了客户的眼睛!)

public void ProvideFault(Exception error, MessageVersion version, ref Message fault){
    if(error is FaultException) {
        fault = Message.CreateMessage(version, ((FaultException<StackOverflowFault>)error).Reason)
    } else if(error is SqlException) {
        // What would Jon Skeet do?
    }   
}

我的问题

这被认为是好的做法吗?并且:如果我已经在适合客户端的应用程序中抛出FaultException -让它们由IErrorHandler (它自动)处理有意义吗?

最佳实践是实现IErrorHandler。这是因为:

  1. 你的代码不是唯一潜在的异常来源。你调用的方法(或者一个bug)可能会导致。net异常。如果您没有在某个地方处理该异常,并且没有使用IncludeExceptionDetailInFaults(在生产环境中不应该这样做),这将看起来像服务崩溃。
  2. 关注点分离:服务代码调用的任何业务层都不应该引用WCF (System.ServiceModel),因此应该抛出标准的。net异常。保持业务层不知道它是如何托管的,使它更易于移植和更可测试。
  3. [FaultContract]类型需要在[OperationContract]上指定。在较大的应用程序中,您希望集中生成Fault,换句话说,知道特定的IErrorHandler返回特定的一组Fault,以便您可以验证契约的Fault类型是否正确。抛出合约方法不明确支持的Fault类型是一个严重的运行时错误。

你可以在你所有的服务方法中复制粘贴一个try/catch块来抛出一个FaultException,但是这是一个可怕的代码气味,并且是IErrorHandler作为一种行为给你的确切功能。所以用IErrorHandler来代替。

将两种模型结合起来是可能的。例如,让IErrorHandler根据需要处理FaultExceptions,但这不是一种常见的做法。

最新更新