Reputation: 3960
I have a WCF service where I am catching an SqlException and then returning it as a FaultException like this
throw new FaultException<SqlException>(...);
And on the client side, I am catching it like this
catch (FaultException<SqlException> e)
{
// do something with exception
}
catch (FaultException<Exception> e)
{
// do something with exception
}
I don't believe I have a problem in my web.config on the service side or the app.config on the client side (a winform client) as I am able to catch FaultException<ArgumentException>
, FaultException<Exception>
, etc. but not FaultException<SqlException>
I have not found anything indicating that I can't pass SqlExceptions down to the client, my operation contract is properly configured with things like [FaultContract(typeof(SqlException))]
, and [FaultContract(typeof(Exception))]
Anyone seen this or know for a fact that I can't (or maybe need to do something special to) pass faults of type SqlException down to the client? Thank you.
Upvotes: 2
Views: 1507
Reputation: 80272
I ran into this problem because I had a breakpoint in the wrong place. I removed all breakpoints with Debug..Delete all Breakpoints
(Ctrl-Alt-F9
), and all of the CommunicationException exceptions disappeared and were replaced with the correct messages coming back.
Yes, the timeout is 60 seconds, so this never should have occurred, so it was probably some weird artifact of Visual Studio 2012.
Upvotes: 0
Reputation: 31071
throw new FaultException<Exception>
is not really how the WCF fault system is intended to be used. The type you specify is serialized across the wire in the <Detail>
element of a SOAP fault. Normally, this type is a WCF data contract class that you write, e.g.
[DataContract]
public class MyFault {
[DataMember]
public string Message {get; set;}
}
throw new FaultException<Exception>
happens to work because Exception
is [Serializable]
, and the DataContractSerializer
is capable of handling [Serializable]
types as well as [DataContract]
types.
However, there are serious limitations to this approach. The DataContractSerializer
does not handle [Serializable]
types very well. Only fields of primitive types (string
, int
, etc) will be transmitted correctly. That is just about OK for a very simple exception type, but for a complex type like SqlException
, it's not good enough.
My suggested solution is: create your own dedicated data contract to pass back the data from SqlException
that you require, then throw that instead. In fact, do this for all exception types, it's more secure and better practice. I use Enterprise Library Exception Shielding to handle this automatically. All that gets passed back to the client is a single GUID value identifying the error data in the server log.
Alternatively, if you are determined to go down the exception route, see this detailed article.
Upvotes: 4