Friday, 14 October 2011

Fault Contract

Service that we develop might get error in come case. This error should be reported to the client in proper manner. Basically when we develop managed application or service, we will handle the exception using try- catch block. But these exceptions handlings are technology specific.
In order to support interoperability and client will also be interested only, what wents wrong? not on how and where cause the error.
By default when we throw any exception from service, it will not reach the client side. WCF provides the option to handle and convey the error message to client from service using SOAP Fault contract.
Suppose the service I consumed is not working in the client application. I want to know the real cause of the problem. How I can know the error? For this we are having Fault Contract. Fault Contract provides documented view for error accorded in the service to client. This help as to easy identity the what error has accord. Let us try to understand the concept using sample example.
Step 1: I have created simple calculator service with Add operation which will throw general exception as shown below
//Service interface
[ServiceContract()]
    public interface ISimpleCalculator
    {
        [OperationContract()]
        int Add(int num1, int num2);
    }
//Service implementation
public  class SimpleCalculator : ISimpleCalculator
    {
    
        public int Add(int num1, int num2)
        {
            //Do something
            throw new Exception("Error while adding number");
            
        }

    }

Step 2: On client side code. Exceptions are handled using try-Catch block. Even though I have capture the exception when I run the application. I got the message that exceptions are not handled properly.
try
   {
      MyCalculatorServiceProxy.MyCalculatorServiceProxy proxy
       = new MyCalculatorServiceProxy.MyCalculatorServiceProxy();
      Console.WriteLine("Client is running at " + DateTime.Now.ToString());
      Console.WriteLine("Sum of two numbers... 5+5 =" + proxy.Add(5, 5));
      Console.ReadLine();
   }
   catch (Exception ex) 
   {
      Console.WriteLine(ex.Message);
      Console.ReadLine();
   }
Step 3: Now if you want to send exception information form service to client, you have to use FaultException as shown below.
        public int Add(int num1, int num2)
        {
            //Do something
            throw new FaultException("Error while adding number");
            
        }
Step 4: Output window on the client side is show below.
Step 5: You can also create your own Custom type and send the error information to the client using FaultContract. These are the steps to be followed to create the fault contract.
  • Define a type using the data contract and specify the fields you want to return.
  • Decorate the service operation with the FaultContract attribute and specify the type name.
  • Raise the exception from the service by creating an instance and assigning properties of the custom exception.
Step 6: Defining the type using Data Contract
    [DataContract()]
    public class CustomException
    {
        [DataMember()]
        public string Title;
        [DataMember()]
        public string ExceptionMessage;
        [DataMember()]
        public string InnerException;
        [DataMember()]
        public string StackTrace;        
    }
Step 7: Decorate the service operation with the FaultContract
    [ServiceContract()]
    public interface ISimpleCalculator
    {
        [OperationContract()]
        [FaultContract(typeof(CustomException))]
        int Add(int num1, int num2);
    }
Step 8: Raise the exception from the service
        public int Add(int num1, int num2)
        {
            //Do something
            CustomException ex = new CustomException();
            ex.Title = "Error Funtion:Add()";
            ex.ExceptionMessage = "Error occur while doing add function.";
            ex.InnerException = "Inner exception message from serice";
            ex.StackTrace = "Stack Trace message from service.";
            throw new FaultException(ex,"Reason: Testing the Fault contract") ;
            
        }
Step 9: On client side, you can capture the service exception and process the information, as shown below.
   try
   {
      MyCalculatorServiceProxy.MyCalculatorServiceProxy proxy 
      = new MyCalculatorServiceProxy.MyCalculatorServiceProxy();
       Console.WriteLine("Client is running at " + DateTime.Now.ToString());
       Console.WriteLine("Sum of two numbers... 5+5 =" + proxy.Add(5, 5));
       Console.ReadLine();
    }
    catch (FaultException<MyCalculatorService.CustomException> ex)
     {
        //Process the Exception
     }

No comments:

Post a Comment