Exception handling in WCF

Leverage fault exceptions in WCF to transmit user friendly error messages to the presentation layer when exceptions occur

Exceptions in WCF

Exceptions in WCF

Exceptions are errors that occur at runtime; exception handling is the technique of handling these runtime errors. You would typically use try, catch, and finally blocks (also known as exception blocks) in your application's code to handle exceptions. If exceptions are not handled properly in the application's code and an exception has occurred at runtime, the execution of the application would terminate.

Exception handling in WCF is not that straight forward – you are constrained to sending .Net objects over the wire and your WCF service can only send serialized data, i.e., SOAP messages to the client. You can handle exceptions in WCF in one of these three ways:

  1. Using FaultException
  2. Using IErrorHandler
  3. Using returnUnknownExceptionsAsFaults

In this post, I will present a discussion on the various ways in which exception messages can be transmitted from the WCF service to the consumers of the service.

Consider this simple WCF service.

[ServiceContract]

public interface IDBManagerService

    {

        [OperationContract]

        void Save(Employee emp);

    }

The IDBManagerService service contract contains one operation contract to persist an employee object to the database.

public class DBManagerService : IDBManagerService

    {

        void Save(Employee emp)

        {

         try

           {

            //Code to store an employee object to the database

           }

           catch(Exception ex)

           {

               throw new Exception(“Error occurred while saving data…”);

           }

        }

    }

Now suppose there is an error connecting to the database or storing the employee object to the database at the time when you are trying to consume the service. You would then get an exception with this message: "System.ServiceModel.FaultException: The server was unable to process the request due to an internal error.  For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .Net Framework 3.0 SDK documentation and inspect the server trace logs."

You can use set the includeExceptionDetailInFaults element to true in the web.config file so that the additional details of the exception are included in the fault to make it more convenient to you to inspect what actually went wrong.

<serviceBehaviors>

  <behavior name="ServiceBehavior">

    <serviceMetadata httpGetEnabled="true"/>

    <serviceDebug includeExceptionDetailInFaults="true"/>

  </behavior>

</serviceBehaviors>

You can also achieve this by writing code. Here is a code snippet that illustrates how you can set this property to true.

    typeof(ServiceDebugBehavior));

    new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true });

You can also set this to true using the ServiceBehavior tag as shown below.

[ServiceBehavior(IncludeExceptionDetailInFaults = true)]

public class DBManagerService : IDBManagerService

{

}

When you try to consume the service again, you would see a more precise exception message.

Using FaultException

However, if you need to pass user friendly exception messages from the service, you should throw fault exceptions. Fault exceptions are exceptions that are thrown by a WCF service when an exception occurs at runtime -- such exceptions are typically used to transmit untyped fault data to the service consumers. You can handle exceptions in your service methods much the same way you do with other methods and then turn them into fault exceptions.

The code snippet below shows the updated service method -- the service method now throws fault exception.

public class DBManagerService : IDBManagerService

    {

        void Save(Employee emp)

        {

            try

            {

               //Code to store an employee object to the database

            }

            catch(Exception ex)

            {

               throw new FaultException(“Error occurred while saving data…”);

            }

        }

    }

You would now need to handle fault exception in your code when consuming this service. You can learn more on fault exceptions in WCF from this MSDN article.

You can also create a custom fault class that is marked with the DataContract attribute.

[DataContract]

public class CustomFault

{

[DataMember]

public string Source;

[DataMember]

public string ExceptionMessage;

[DataMember]

public string InnerException;

[DataMember]

public string StackTrace;

}

The following code snippet illustrates how you can use the CustomFault class to throw strongly-typed FaultException.

void Save(Employee emp)

{

try

{

  //Code to save the employee object into the database

}

catch (Exception ex)

{

CustomFault cx = new CustomFault();

throw new FaultException(ex, new FaultReason("This is a strongly typed faulted exception"));

}

}

You would also need to specify the FaultContract attribute on your service method that would raise FaultException. The modified Save method would look like this.

[ServiceContract]

public interface IDBManagerService

    {

        [OperationContract]

        [FaultContract]

        void Save(Employee emp);

    }

Using returnUnknownExceptionsAsFaults

You can use the returnUnknownExceptionsAsFaults attribute in the service behavior configuration to raise an exception as a SOAP fault automatically. The following code snippet illustrates how you can achieve this.

<behaviors>

      <behavior name="DataServiceBehavior"

                 returnUnknownExceptionsAsFaults="True">

      </behavior>

</behaviors>

Handling exceptions globally

Another way to handle exceptions in WCF is by implementing the IErrorHandler interface on your service class to handle all exceptions globally and provide a SOAP compliant FaultException. This interface contains two methods -- HandleError and ProvideFault. While the former is used to perform some activity with the error, the latter is used to return a fault message. Note that you can also configure IErrorHandler (turn it on or off) in your service configurable file.

This article is published as part of the IDG Contributor Network. Want to Join?

From CIO: 8 Free Online Courses to Grow Your Tech Skills
Notice to our Readers
We're now using social media to take your comments and feedback. Learn more about this here.