Data Access has been discontinued. Please refer to this page for more information.

Error Handling

This article is relevant to entity models that utilize the deprecated Visual Studio integration of Telerik Data Access. The current documentation of the Data Access framework is available here.

This topic demonstrates how to enable the fault behavior of your WCF Service and how to handle exceptions on the client.

What are Faults?

Faults and exceptions are not the same thing. Exceptions are a .NET Framework mechanism that is used to communicate problems during the program executions. You can throw, catch, handle, and ignore exceptions so that they can be further propagated up the call stack. At some point, they should be handled or .NET will terminate the thread in which the exception is thrown. On the other hand, faults are SOAP mechanism for transferring errors from a service to a client.

Configuring Fault Behavior of your WCF Service

This section shows how to enable the fault behavior of your WCF Service and what type of information will be sent with the fault.

The FaultException Class

When your service implementation throws a FaultException, WCF takes care of serializing that back to the customer as a SOAP fault. There are two versions of the class:

  • FaultException - sends untyped fault data to the client.
  • FaultException<T> - a generic version, used to send typed fault data to the client. The type argument represents the detailed fault information that will be serialized to the client as part of the SOAP fault message. You can specify your own custom class as the type parameter. Client applications catching the fault exception can access the fault information by getting it from the exception object's Detail property.

The FaultContractAttribute

The FaultContractAttribute enables you to declare which faults a given service operation might issue. The attribute can be applied multiple times on a single operation; for instance, if your operation might return different types of faults.

The following example demonstrates, first, how to declare a service might issue faults, and, second how the service operation might create and throw a new FaultException.

[ServiceContract]
public interface IEntitiesModelService
{
   [OperationContract]
   [FaultContract( typeof( string ) )]
   [FaultContract( typeof( DemoFault ) )]
   CarDto GetCar( string make, string model );
}

public partial class EntitiesModelService
{
   public CarDto GetCar( string make, string model )
   {
       if ( string.IsNullOrEmpty( make ) || ( string.IsNullOrEmpty( model ) ) )
       {
           throw new FaultException<string>( "Invalid Parameters." );
       }

       CarDto car = this.CarService.GetAll().FirstOrDefault(c => c.Make == make && c.Model == model);
       if ( car == null )
       {
           throw new FaultException<DemoFault>( new DemoFault( string.Format( "Cannot find {0} {1}.", make, model ) ) );
       }

       return car;
   }
}

[DataContract]
public class DemoFault
{
   public DemoFault( string errorText )
   {
       this.ErrorText = errorText;
   }
   [DataMember]
   public string ErrorText
   {
       get;
       set;
   }
}
<ServiceContract>
Public Interface IEntitiesModelService
 <OperationContract, FaultContract(GetType(String)), FaultContract(GetType(DemoFault))>
 Function GetCar(ByVal make As String, ByVal model As String) As CarDto
End Interface

Partial Public Class EntitiesModelService
    Public Function GetCar(ByVal make As String, ByVal model As String) As CarDto _
        Implements IEntitiesModelService.GetCar
        If String.IsNullOrEmpty(make) OrElse (String.IsNullOrEmpty(model)) Then
            Throw New FaultException(Of String)("Invalid Parameters.")
        End If
        Dim car As CarDto = Me.CarService.GetAll(). _
            FirstOrDefault(Function(c) c.Make = make AndAlso c.Model = model)
        If car Is Nothing Then
            Throw New FaultException(Of DemoFault)(New _
                DemoFault(String.Format("Cannot find {0} {1}.", make, model)))
        End If
        Return car
    End Function
End Class

<DataContract>
Public Class DemoFault
 Public Sub New(ByVal errorText As String)
  Me.ErrorText = errorText
 End Sub
 <DataMember>
 Public Property ErrorText() As String
End Class

Handling Exceptions in the Client

On the client side, a FaultException is caught just like any other exception, as it's shown here:

EntitiesModelServiceClient serviceClient = new EntitiesModelServiceClient();
try
{
   CarDto car = serviceClient.GetCar( "Opel", "Astra" );
   Console.WriteLine( car.CarID.ToString() );
}
catch ( FaultException<string> exception )
{
   Console.WriteLine( exception.Detail );
}
catch ( FaultException<DemoFault> exception )
{
   Console.WriteLine( exception.Detail.ErrorText );
}
Dim serviceClient As New EntitiesModelServiceClient()
Try
 Dim car As CarDto = serviceClient.GetCar("Opel", "Astra")
 Console.WriteLine(car.CarID.ToString())
Catch exception As FaultException(Of String)
 Console.WriteLine(exception.Detail)
Catch exception As FaultException(Of DemoFault)
 Console.WriteLine(exception.Detail.ErrorText)
End Try

The exceptions defined in the catch statements are the generic version of the FaultException class. The Detail property exposes the instance of the fault type returned by the service, e.g. string or DemoFault.