How can I ensure exception type safety?

237 Views Asked by At

I am using some code adapted from Lowy's ServiceModelEx to package an exception inside a FaultException, send it across the wire, and then unpack it on the client as a .NET Exception. My server can throw exceptions of theoretically any kind, but let's use a SqlException as an example.

Lowy uses reflection to unpack, so the code needs to examine the type of the exception to determine whether it can construct a valid object:

    static Exception ExtractException(ExceptionDetail detail)
    {
        Exception innerException = null;
        if (detail.InnerException != null)
        {
            innerException = ExtractException(detail.InnerException);
        }
        Type type = Type.GetType(detail.Type);
        Debug.Assert(type != null, "Make sure this assembly contains the definition of the custom exception");
        Debug.Assert(type.IsSubclassOf(typeof(Exception)));

        //...
    }

Two questions

  1. With SqlExceptions, that first Debug.Assert fails. Trying to get them to resolve on the client, I have set a reference to System.Data, but no luck. I'm assuming this is because, without any actual System.Data invocation in that client, the compiler removes the reference? What can I do, in the short term, to get my client to resolve that .GetType call?

  2. What is the correct way to "rethrow" the LambdaException as a base ExceptionDetail without losing granularity of detail (e.g. StackTrace) and without needing any assembly reference on the client side? Is this even possible?

EDIT: this is the source that wraps the ExceptionDetail as a FaultException on the server. Again, this is mostly from Lowy's ServiceModelEx:

    public static void PromoteException(Type serviceType, Exception error, MessageVersion version, ref Message fault)
    {
        //Is error in the form of FaultException<T> ? 
        if (error.GetType().IsGenericType && error is FaultException)
        {
            Debug.Assert(error.GetType().GetGenericTypeDefinition() == typeof(FaultException<>));
            return;
        }

        ExceptionDetail exdetail = new ExceptionDetail(error);
        FaultException<ExceptionDetail> faultException = new FaultException<ExceptionDetail>(exdetail);

        MessageFault messageFault = faultException.CreateMessageFault();
        fault = Message.CreateMessage(version, messageFault, faultException.Action);

        //...
    }
0

There are 0 best solutions below