I am currently doing some research on how to handle exceptions and let the client know in a winforms app which calls a WCF service (Self-hosted in a windows service). What is the best way for this? A couple of questions:
1) If I let an exception propagate, it'll come up on the client side.
2) What's the best way to catch the exception on the client side? Is it:
catch (FaultException<T> fault) { }
(Empty catch block just for demo purposes). Or is there another way?
You will need to put each of your calls in a try{}catch{} block since that is where it will be propagated from on the client side, possibly encompassing some of the possible exception handing in some sort of proxy to hide the WCF specific handling.
Using exception shielding you can also specify custom FaultExceptions and decorate the method with attributes to allow that exception to be sent down to the client. That way you can be a little more intelligent when the exception arises.
e.g.
try{
... call service
}catch(FaultException<TimeoutFault> ex){
.. try one more time
}catch(FaultException<InvalidSelection> ex){
... show message to user from ex.Details.InvalidProperty
}catch(FaultException){
... handle
}catch (CommunicationException ex){
... remember this is WCF so the call itself might fail
}catch(Exception ex){
... handle
}
Id reccomend reading http://blogs.msdn.com/b/pedram/archive/2008/01/25/wcf-error-handling-and-some-best-practices.aspx as it has a few good tips/
You should always at least catch CommunicationException, of which FaultException (and others) derives from. Generally you will only get FaultException during development of your service (set IncludeExceptionDetailInFaults to get better faults while debugging). CommunicationException can occur when the service is not running, among many other reasons. You may want to read this MSDN article for more information about error handling in your WCF service.
Related
whenever cal the PostAsJsonAsync at the time internet disconnected then I want to show the message
but catch block didn't caught the exception for PostAsJsonAsync. before I had worked
GetfromjsonAsync that will caught the exception if internet disconnected but I need when we use
PostAsJsonAsync at the time I want to catch the excption,
please help me.
thanks
whenever cal the PostAsJsonAsync at the time internet disconnected then I want to show the message
but catch block didn't caught the exception for PostAsJsonAsync. before I had worked
GetfromjsonAsync for external api that will caught the exception if internet disconnected but I
need when we use PostAsJsonAsync at the time I want to catch the excption,
I'm learning about FaultException and CLR Exceptions in the context of WCF services but something is not clear.
In the book "Learning WCF" it says that when a service throws a normal CLR Exception it's caught by the service model, the service model constructs a SOAP message from that, sends it back to the client, and the exception is thrown at the client again. There the channel is faulted.
So I've built a service which throws a NullReferenceException.
A client calls the service, catches the exception and print the CommunicationState.
try
{
x = Proxy.Call(); // throws NullReferenceException at the service
}
catch (Exception ex) // or CommunicationException is the same
{
MessageBox.Show("" + Proxy.InnerChannel.State);
}
But the State member stays on Opened and I can call the service forever....
What is correct here? Should a client go into faulted state when a service throws a CLR exception and stays in Opened state when a service throws a FaultException? Or does it always stay open?
I can not find official confirmation, but here is what going on in my opinion:
You using BasicHttpBinding which does not keep connection open, but creates new one on every request. If you switch to NetTcpBinding, you will see expected behavior(just tested locally)
When error occures session's state gets in fault state and since binding such as basicHttpBinding does not support session at all you cannot distincly see that connection is in faulted state. Try to make use of binding which supports session such as netTcpBinding and you should discover that session, after exception being thrown, is not accessible.
I noticed that if you do a throw new InvalidCastException for example, the channel state on the client side is faulted. But if you throw new FaultException, the channel state on the client side is opened.
By curiosity, what is the reason why one faults the channel and the other doesn't?
The FaultException is a special case in WCF. It's meant to indicate that something happened on the service side that was an error, but at the same time, not fault the channel. This makes sense, given you can embed this information into the contract using the FaultContractAttribute to expose what can be expected from a contract.
Other exceptions are not really translatable in the WS world. Exceptions are a technology-specific abstraction, and each technology stack has a different representation of that abstraction (or in some cases, none at all).
That being said, when an exception that is not a fault exception is thrown on the server side, it is seen as catastrophic by the WCF runtime, and the channel must be faulted, as it is not known if you can proceed or not.
However, using FaultException, it implies you have some foresight into the conditions around why it was thrown and whether or not the underlying channel has been impacted or not.
I want to know what are the cases in which WCF proxy (generated by vs2008 or svcutil) becomes faulted (fault state)? so I can recreate new instance and avoid use the faulted one.
currently I am handling TimeoutException,FaultException,CommunicationObjectAbortedException
try
{
client.Method1(args);
}
catch (TimeoutException)
{
client.Abort();
ReCreate();
}
catch (FaultException)
{
client.Abort();
ReCreate();
}
catch (CommunicationObjectAbortedException)
{
client.Abort();
ReCreate();
}
I think I can avoid all these types and handle only the parent CommunicationException, is this sufficient? I need comments
Any uncaught exception on the server side that isn't handled and converted into a FaultException or FaultException<T> will likely fault your channel. In a per-call scenario or a one-way scenario, you often don't really care about the channel being faulted, but in a session-based scenario, you definitely will!
Your best bet is to really try and catch all exceptions on the server side and either just suppress them (log them on the server and don't do anything), or return them to the client in a FaultException way.
In order to do that, your service implementation should also implement the IErrorHandler interface which allows you to do just that - catch all exceptions and either logging+suppressing them, or converting them to SOAP faults.
Marc
WCF proxy object can become faulted because of any sort of exception except a faultException. So basically you best bet is just to check the proxy state and of it is faulted create a new one.
Another thing to keep in mind is that faulted is related to WCF sessions. If you don't need WCF sessions make sure to turn them off and you have prevented a whole series of possible issues.
I want to catch all unhandled exceptions thrown in a remote object on the server and log them there before I translate them into some custom exception so that specific exceptions do not cross the client/server boundary.
I think I have to use a custom channel sync, but can anyone confirm this and/or have any other advice to give?
I would use the Microsoft Enterprise Library Exception Handling app block -- it lets you handle errors and convert specific types of exception to a different type of exception before rethrowing to the client.
After finding Eliyahu Baker's helpful blog post and reading chapter 12 of Rammer's Advanced .NET Remoting I wrote a custom channel sink that does what I want. This intercepts any exception and logs it locally before sending it on to the client.
Ideally, I'd like to log the exception and raise a more generic one for the client, but I haven't cracked that nut yet.