Atrotygma
Atrotygma

Reputation: 1143

Handling WCF exceptions/faults along with FaultException AND IErrorHandler

I'm interested in implementing a proper exception handling for my WCF application. After a quick google ride, I've come across two solutions.

  1. Providing FaultExceptions for the client.
  2. General exception handling using 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

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

Catching unhandled exceptions with IErrorHandler and log them.

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

Upvotes: 0

Views: 1940

Answers (1)

ErnieL
ErnieL

Reputation: 5801

Best practice is to implement 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. 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.
  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. 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]. 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. Throwing a Fault type that the contract’s method does not explicitly support is a nasty runtime error.

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. So use IErrorHandler instead.

Combining the two models is possible. For example have IErrorHandler process FaultExceptions as needed, but this is not a common practice.

Upvotes: 1

Related Questions