简体   繁体   English

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

[英]Handling WCF exceptions/faults along with FaultException AND IErrorHandler

I'm interested in implementing a proper exception handling for my WCF application. 我对为WCF应用程序实施适当的异常处理感兴趣。 After a quick google ride, I've come across two solutions. 快速浏览Google之后,我遇到了两种解决方案。

  1. Providing FaultExceptions for the client. 为客户端提供FaultExceptions
  2. General exception handling using IErrorHandler . 使用IErrorHandler常规异常处理。

What I didn't found, though, was a practical example that combines the two methods - if this is even considered as good practice . 但是,我没有找到一个结合了这两种方法的实际示例- 如果这甚至被认为是一种很好的做法

My thoughts: 我的想法:

Throwing FaultExceptions with own detail types 使用自己的详细信息类型引发FaultExceptions

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

Catching unhandled exceptions with IErrorHandler and log them. 使用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.");
    }
}

...and provide faults based on the exception type ...并根据异常类型提供故障

(not everything is for the clients eyes!) (不是所有的东西都是给客户看的!)

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?
    }   
}

My question 我的问题

Is this considered as okay practice? 这被认为是可以的做法吗? And: If I'm already throwing FaultException in the application that are suitable for the client - does it makes sense to let them be handled by IErrorHandler ( which does it automatically )? 并且:如果我已经在适合客户端的应用程序中抛出了FaultException-让IErrorHandler自动执行 )处理它们是否有意义?

Best practice is to implement IErrorHandler. 最佳实践是实现IErrorHandler。 This is because: 这是因为:

  1. Your code isn't the only potential source of exceptions. 您的代码不是异常的唯一潜在来源。 The methods you call (or a bug) might result in a .NET Exception. 您调用的方法(或错误)可能会导致.NET异常。 If you don't handle that exception somewhere and aren't using IncludeExceptionDetailInFaults (which you shouldn't in production) this will look like a service crash. 如果您未在某处处理该异常,并且未使用IncludeExceptionDetailInFaults (您不应该在生产中使用),这将看起来像服务崩溃。
  2. Separation of Concerns : Any business layer called by the service code should not reference WCF ( System.ServiceModel ) and therefore should be throwing standard .NET exceptions. 关注点分离 :服务代码调用的任何业务层都不应引用WCF( System.ServiceModel ),因此应引发标准.NET异常。 Keeping the business layer unaware of how its hosted makes it more portable and more testable. 使业务层不知道其托管方式如何使其更可移植和更可测试。
  3. [ FaultContract ] types need to be specified on the [ OperationContract ]. 需要在[ OperationContract ]上指定[ FaultContract ]类型。 In larger applications you want the Fault generation to be centralized… In other words know that a particular IErrorHandler returns a particular set of Faults so that you can validate the Contracts Faults types are right. 在较大的应用程序中,您希望将故障生成集中化……换句话说,要知道特定的IErrorHandler返回特定的一组故障,以便可以验证“合同故障”类型是否正确。 Throwing a Fault type that the contract's method does not explicitly support is a nasty runtime error. 抛出合同方法未明确支持的Fault类型是一个讨厌的运行时错误。

You could copy and paste a try/catch block in all your service methods to throw a FaultException, but it's a horrible code smell and is the exact functionality that IErrorHandler is giving you as a behavior. 您可以在所有服务方法中复制并粘贴try / catch块以引发FaultException,但这是一种可怕的代码味道,并且是IErrorHandler赋予您行为的确切功能。 So use IErrorHandler instead. 因此,请改用IErrorHandler。

Combining the two models is possible. 可以将两个模型结合起来。 For example have IErrorHandler process FaultExceptions as needed, but this is not a common practice. 例如,根据需要让IErrorHandler处理FaultExceptions,但这不是常见的做法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM