I'm trying to come up with a simple, easy to use design pattern for error handling in a .net wcf service (specifically a silverlight enabled wcf service). If an exception gets thrown in the service method the silverlight application will see a CommunicationException stating "The remote server returned an error: NotFound —> " and possibly a stack trace depending in your settings, which is entirely not useful because it doesn't tell you the actual error, and usually the real error is not "NotFound".
Reading up on web services and wcf services and exceptions, You need to throw soap/wcf standard exceptions such as FaultException or SoapException. So for a wcf service you need to wrap each method in a try catch, catch each exception, wrap it in a FaultException and throw it. At least that is my understanding, correct me if I am wrong.
So I've created my design pattern:
[ServiceContract(Namespace = "http://MyTest")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class DataAccess
{
/// <summary>
/// Error class, handle converting an exception into a FaultException
/// </summary>
[DataContractAttribute]
public class Error
{
private string strMessage_m;
private string strStackTrace_m;
public Error(Exception ex)
{
this.strMessage_m = ex.Message;
this.strStackTrace_m = ex.StackTrace;
}
[DataMemberAttribute]
public string Message
{
get { return this.strMessage_m; }
set { this.strMessage_m = value; }
}
[DataMemberAttribute]
public string StackTrace
{
get { return this.strStackTrace_m; }
set { this.strStackTrace_m = value; }
}
//Convert an exception into a FaultException
public static void Throw(Exception ex)
{
if (ex is FaultException)
{
throw ex;
}
else
{
throw new FaultException<Error>(new Error(ex));
}
}
}
[OperationContract]
[FaultContract(typeof(Error))]
public void TestException()
{
try
{
throw new Exception("test");
}
catch (Exception ex)
{
Error.Throw(ex);
}
}
}
So to make a long story short, I'm still not getting the correct error in my silverlight application. I inspect the AsyncCompletedEventArgs.Error object and it still contains a CommunicationException object with the generic error. Help me come up with a nice simple design pattern to allow me to easily throw the correct exception from the service, and easily catch it in the application.
Best Answer
I would suggest you to centralize the error handling of your WCF service instead of putting try/catch on every method. To do this you can implement the IErrorHandler interface:
The
ProvideFault
method is called whenever one of yourOperationContract
throws an exception. It will convert the exception into a custom definedFaultContract
and send it to the client. This way you no longer need to put try/catch in every method. You can also send a differentFaultContract
depending on the exception thrown.On the client side you need to catch
FaultException<DataAccessFaultContract>
every time you call a method on your web service.