Handling WCF Custom Exceptions when using ObjectDataSource
WCF uses a default SOAP exception called FaultException which allows for creating custom WCF Exceptions using the template FaultException<TDetail>. Exception Handling in WCF Web Service shows an example of creating and catching a custom FaultException error.
A difficulty with the example comes into play when using ObjectDataSource to bind to a WCF business object. The problem is that you cannot catch the exception in a try/catch statement like the example shows, so it will be an unhandled exception. ObjectDataSource, and other DataSource controls, don’t load data (or execute the select statement) until after Page_Load and other events have fired, so your try/catch in Page_Load won’t work. It seems the logic, which is forced upon you by ASP.Net, is that it ensures the data returned is up to date by executing all other events first. So in this case, errors from the WCF are going to flow to “special scopes” of the web application. Exception-handling in ASP.NET shows the various places errors can be handled. Let say the error will be handled by the Application_Error delegate in Global.asax. When the error flows to Global.asax, you have to use Server.GetLastError().GetBaseException() which you can put into an Exception object, but then you need to figure out the type to cast it into the correct exception. I could not find an example of how to do this, so I’m posting what I came up with.
Let’s say I have a custom WCF error called FaultException<SampleFaultException>. In my code I need to check if that is the error type. Here is the code in the Global.asax:
void Application_Error(object sender, EventArgs e)
{/* List of custom Exceptions from AddressService WCF
*
* System.ServiceModel.FaultException`1[SampleFaultException]
*/
//get the base error type
Type errType = Server.GetLastError().GetBaseException().GetType();
//get the generic base exception
Exception err = Server.GetLastError().GetBaseException();
//check the error type to later cast the exception
System.Text.RegularExpressions.Regex regSampleFaultException = new Regex(”SampleFaultException”);
System.Text.RegularExpressions.Match matchSampleFaultException = regSampleFaultException.Match(errType.ToString());
System.Text.RegularExpressions.Regex regFaultException = new Regex(”FaultException”);
System.Text.RegularExpressions.Match matchFaultException = regFaultException.Match(errType.ToString());
//process errors based on the exception
Response.Clear();
//check for SampleFaultException
if (matchSampleFaultException.Success)
{
Response.Write(”<pre>Start - This is a SampleFaultException</pre>”);
System.ServiceModel.FaultException<SampleFaultException> err3 = (System.ServiceModel.FaultException<SampleFaultException>)err;
Response.Write(”<pre>” + err3.Detail.errorcode + ” - ” + err3.Detail.message + “</pre>”);
Response.Write(”<pre>End - This is a SampleFaultException</pre>”);
}
//check for pure FaultException where is doesn’t have SampleFaultException
else if( (!matchSampleFaultException.Success) && (matchFaultException.Success))
{
Response.Write(”<pre>Start - This is a FaultException</pre>”);
System.ServiceModel.FaultException err3 = (System.ServiceModel.FaultException)err;
Response.Write(”<pre>” + err3.Message + “</pre>”);
Response.Write(”<pre>End - This is a FaultException</pre>”);
}
Server.ClearError();
}
