Unwrap WCF FaultException

One of the huge benefits from WCF is it’s extension feature, two good examples are WCFNhinbernateContext in Igloocommons and Errorhandler. We use both of them in our applications and really like it.

The disadvantage is how to handle the exception threw in Detach(), unfortunately this exception won’t be covered by FaultContract, so the exception will be seen as the regular FaultException with no details at client side.

Turn on “IncludeExceptionDetailInFaults” can make it better, we prefer to put it in code to not worry about configuration, because this is a must-have settings for WCF.


[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
 class TestService : ITestService

We can see the fault/exception details by adding this, but, developers want strongly typed exception:


        public TResult CallService<TResult>(Func<TServiceContract, TResult> function)
        {
            Client client = new Client();
            TResult result = default(TResult);

            try
            {
                result = function(client.Service);
                if (client.State != CommunicationState.Faulted)
                {
                    client.Close();
                }
                else
                {
                    client.Abort();
                }
            }
            catch (Exception e)
            {
                client.Abort();
                HandleException(e);
            }

            return result;

        }

        /// DatabaseException is thrown in WCFExtension.Detach()
        public virtual void HandleException(Exception ex)
        {
            if (ex is FaultException<ExceptionDetail>)
            {
                var e = (FaultException<ExceptionDetail>) ex;
                string error;

                if (e.Detail.InnerException != null)
                {
                    error = e.Detail.InnerException.Message;

                    if (e.Detail.Type.Equals(typeof(DatabaseException).ToString()))
                    {
                       throw new DatabaseException(e.Detail.InnerException.Message, ex);
                    }
                }

            }
       }

Even further, I can do this rewrap/unwrap for other faultexception, so I don’t need investigating ExceptionMarshallingBehavior described here and here.


            if (ex is FaultException && ex.GetType().IsGenericType)
            {
                    throw (Exception) ex.GetType().GetProperty("Detail").GetValue(ex, null);
            }

This is a too-new idea, I’ll test it in our app first.

About close vs. about. Here is a very good explanation.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s