I have a simple IPC mechanism that uses WCF and named pipes. My goal is to propagate exception details (including the stacktrace) to the client for logging purposes (the rest of the application logging is located on the client).
If I use the following code I am able to catch FaultException<Exception> on the client and see exception details:
Contract:
[ServiceContract]
public interface IService
{
[OperationContract]
[FaultContract(typeof(Exception))]
void DoSomething();
}
Implementation:
public class Service : IService
{
public void DoSomething()
{
try
{
ThisWillThrowAnException();
}
catch (Exception e)
{
throw new FaultException<Exception>(e);
}
}
}
Client:
public void CallServer()
{
try
{
proxy.DoSomething();
}
catch (FaultException<Exception> e)
{
Console.WriteLine("Caught fault exception!");
}
}
This works fine and I see the message printed on the console. However, if I want to use my own derived exception instead of the base Exception class, it fails.
Custom Exception:
[Serializable]
public class MyException : Exception
{
public MyException () { }
public MyException (string message) : base(message) { }
public MyException (string message, Exception inner) : base(message, inner) { }
protected MyException (
SerializationInfo info,
StreamingContext context)
: base(info, context) { }
}
Change the FaultContract on IService.DoSomething to
typeof(MyException).
Change the throw clause in Service to
new FaultException<MyException>(new MyException(e.Message, e);
Change the catch clause in the client to
catch (FaultException<MyException> e)
When I execute this, a CommunicationException is caught on the client with the error: System.ServiceModel.CommunicationException: There was an error reading from the pipe: The pipe has been ended. (109, 0x6d).
The MyException class is in a shared library available to both the client and server.
This question is very similar to this question, but that did not help me.