Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Exception Handling in WCF

4.33/5 (7 votes)
9 Nov 2010CPOL3 min read 53.3K  
Exception Handling in WCF

We have been doing exception handling in managed application using try-catch block with Exception or its derived Custom Exception objects. But this mechanism is very much .NET Technology specific. When we develop SOA applications, our application is not limited to merely one technology or single loyal client. So the communication process of this service or service method level errors to client via wire becomes a little bit tricky. WCF has two types of error handling mechanisms: one is by as usual Exception objects, and the other is by SOAP fault message. SOAP fault is used to marshall .NET exceptions to client in much readable and convenient way to support interoperability. With use of SOAP fault, the verbose exception message is reduced to Code and Message. For this System.ServiceModel namespace comes FaultException class and FaultContract attribute.

Let’s come to see from the example how to do exception handling in WCF application. Before this, write our service first.

C#
namespace WcfSvc
{
[ServiceContract]
public interface IBasicMathService
{
[OperationContract]
int Subtraction(int x, int y);

[OperationContract]
int Multiplication(int x, int y);

[OperationContract]
[FaultContract(typeof(BasicMathFault))]
int Addition(int x, int y);
}

[DataContract]
public class BasicMathFault
{
//
[DataMember]
public string Source;

[DataMember]
public string ExceptionMessage;

[DataMember]
public string InnerException;

[DataMember]
public string StackTrace;
}
}

And its implementation is as:

C#
public class BasicMath : IBasicMathService
{
public int Addition(int x, int y)
{
//
int result = 0;
try
{
result = (x + y);
}
catch
{
BasicMathFault ex = new BasicMathFault();
ex.Source = "BasicMath.Addition method";
ex.ExceptionMessage = "Could not perform addition operation.";
ex.InnerException = "Inner exception from math service";
ex.StackTrace = "";
//Throwing strongly-typed FaultException
throw new FaultException(ex, new FaultReason(
    "This is an error condition in BasicMath.Addition method")); }
return result;
}

public int Multiplication(int x, int y)
{
//Due to some calculation error condition, let’s assume we are throwing this error.
//Throwing simply FaultException
throw new FaultException(new FaultReason(
    "Error occurred while processing for the result"), new FaultCode(
    "mutliplication.method.error"));
}

public int Subtraction(int x, int y)
{
//Exception we generally throw in managed application in the form of Exception object
throw new NotImplementedException("Method still not implemented");
}
}

This is our typical service related code. If we see IBasicMathService interface and its implementation in BasicMath class, we have: Addition(x,y) method decorated with FaultContract attribute in IBasicMathService class, Subtraction(x,y) method using simple Exception throwing mechanism, Multiplication(x,y) method using simple FaultException object, and Addition(x,y) method using strongly-typed fault of type BasicMathFault in FaultException object.

So what does all this mean to the client, and how exception is transmitted to the client? Let’s answer with these three examples in our client code.

A) Throwing Simple Exception

C#
private void SubtractIntegers()
{
try
{
obj = new BasicmathServiceRef.BasicMathServiceClient();
int result = obj.Subtraction(10, 15);
}
catch (Exception ex)
{
Response.Write(ex.Message + "
");
}
}

When this method is called, client receives verbose error message from WCF as: “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 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.”

If we closely take a look at this error information, we come across two things: turn on\off IncludeExceptionDetailInFaults value, either through ServiceBehaviorAttribute of the class containing this method, or modify IncludeExceptionDetailInFaults value in configuration file or section of this service.

Either of these two things is pretty easy.

a) Decorate BasicMath class as:

C#
[ServiceBehavior(IncludeExceptionDetailInFaults = false)]
public class BasicMath : IBasicMathService
{

b) Or, modify in config file:

By default, this key value is false. If we make it true, the verbose error message that we received will be reduced to human readable message that we passed in the constructor of NotImplementedException. “Method still not implemented”

While debugging WCF exception, one may encounter error in the service like “xyz exception unhandled by user code”. This is somewhat misleading, but there is no need to worry.

B) Throw Exception of FaultException Type

C#
private void MultiplyIntegers()
{
try
{
obj = new BasicmathServiceRef.BasicMathServiceClient();
int result = obj.Multiplication(10, 15);
}
catch (FaultException ex)
{
Response.Write(ex.Message + "
");
}
}

On calling this method, WCF will serialize the exception as a Fault message and return to the client as: “Error occurred while processing for the result”.

However, client is unlikely to receive verbose error message if we throw exception of type FaultException even key IncludeExceptionDetailInFaults is true or false. If we see the exception thrown code,

C#
throw new FaultException(new FaultReason("Error occurred while processing for the result"), 
                         new FaultCode("mutliplication.method.error"));

we have used FaultCode. Client can use this specific fault code contained in FaultException code to take a decision, but this approach becomes more of procedural by many if-else condition to branch out code something like:

C#
if (ex.Code.Name == "mutliplication.method.error")
{
Response.Write(ex.Message + "
");
}

C) Throwing With Strongly Typed Fault

C#
private void AddIntegers()
{
try
{
obj = new BasicmathServiceRef.BasicMathServiceClient();
int result = obj.Addition(10, 15);
}
catch (FaultException ex)
{
Response.Write(ex.Message + "
");
}
}

With this approach, the client will be able to explicitly handle fault of only that type whose service method is to be used by client. Here, we are using BasicMathFault type. At the service level, the specific method has to be decorated with FaultContract attribute so that exception can be serialized as:

C#
[OperationContract]
[FaultContract(typeof(BasicMathFault))]
int Addition(int x, int y);

The detail of fault type is up to our convenient level to let WCF serialize only needful information to client.

When we call this Addition(x,y) method, one may receive this error message if an exception occurs. “This is an error condition in BasicMath.Addition method.”

Thus, we see how we can do exception handling in WCF.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)