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

时间:2013-06-12 15:22:59

标签: c# .net wcf web-services exception

我有兴趣为我的WCF应用程序实现适当的异常处理。快速谷歌之后,我遇到了两个解决方案。

  1. 为客户提供FaultExceptions
  2. 使用IErrorHandler进行常规异常处理。
  3. 但我没有找到的是一个结合了两种方法的实际例子 - 如果这被认为是良好的做法

    我的想法:

    使用自己的详细信息类型抛出FaultExceptions

    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自动执行)处理它们是否有意义?

1 个答案:

答案 0 :(得分:1)

最佳做法是实现IErrorHandler。这是因为:

  1. 您的代码不是唯一可能的异常来源。您调用的方法(或错误)可能会导致.NET异常。如果您没有在某处处理该异常并且未使用IncludeExceptionDetailInFaults(您不应该在生产中),这将看起来像服务崩溃。
  2. 关注点分离:服务代码调用的任何业务层都不应引用WCF(System.ServiceModel),因此应抛出标准的.NET异常。保持业务层不知道托管如何使其更便携,更易于测试。
  3. [FaultContract]类型需要在[OperationContract]上指定。在较大的应用程序中,您希望将故障生成集中在一起......换句话说,知道特定的IErrorHandler返回一组特定的故障,以便您可以验证Contracts Faults类型是否正确。抛出契约方法未明确支持的Fault类型是一个讨厌的运行时错误。
  4. 您可以在所有服务方法中复制并粘贴try / catch块以抛出FaultException,但它是一种可怕的代码味道,并且是IErrorHandler为您提供的行为的确切功能。所以请改用IErrorHandler。

    可以组合这两种模型。例如,IErrorHandler根据需要处理FaultExceptions,但这不是常见做法。