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.
Related
I am using netMsmqBinding. The service goes to faulted state. It is hosted in windows service.
One reason i know is when there is an unhandled exception the service goes to faulted state.
My whole code is enclosed in try catch block. So my understanding is every exception will come come in catch and will be handled there.
We are getting an exception in our production environment. How can i create an exception that makes the channel in faulted state. Below is the screen shot of the trace
trace detail
The exception came on a different thread and faulted the channel. Can this be a reason
I use an C# Console Application to put and read messages of the MQ..
When the application starts, it connect once with the MQ and then the connection should be always upholded.
The program runs every 30 sec and check if new messages are in the queue or a database(to put them on the queue) and check the isConnected-variable if its true.
But what happen if an exception(2009 - connection broke) in the Put/Get occur? Will the isConnected automatically set to false?
Is the connection automatically disconnected or do I have to call Disconnect() in the error handling?
Thanks!
To answer your exact question, for a basic .net application (non XMS) using MQQueue for put/get, if you get CERTAIN bad return codes from the underlying API call which indicates a connection issue, MQ will attempt an MQBACK and an MQDISC for you and will result in the connection handle being invalidated (IsConnected would return false) and an exception being thrown. However if an exception occurs outside those return codes then no attempt is made to do anything with the connection.
Basically you should not code an application relying on this behaviour, when the most simple answer is to always disconnect if you get an exception which relates to the quality of the connection or queue manager. For example, a no message available etc type exception doesnt mean you need to disconnect but a connection broken obviously does. There is no harm in calling disconnect on an already disconnected connection.
When I try to access (open a connection to) an offline sql server instance (service turned off) from my web service, no exception is thrown, just a brief 5 sec timeout followed by return (I put the breakpoint way out in my controller, not sure what the connection object returns yet during the call to open).
I'm trying to simulate a scenario where the DB is not available to the webservice, and figured an exception would be thrown and I could just log the error.
Any suggestions on how to properly detect DB connection issues (I'm guessing I need to look to see what the connection object returns when calling open). It'd be nice to just have an exception bubble up though.
Thanks.
A connection timeout will be thrown for sure unless your thread is being aborted before that by a web server timeout. Placing a try/catch in your controller would certainly catch the DB connection timeout.
You should post code, as SqlConnection.Open() definitely would throw an exception but if you're using some other call/code to open the connection and it's getting swallowed then it is obviously difficult to determine a root cause.
My guess is that you are getting back a Connection object that is not connected, to check if it's connected:
if (conn.State == ConnectionState.Closed)
{
...
}
I am using a WCF Rest service which is called via JS ajax calls.
For some methods if an exception occurs it is caught and wrapped in a WebFaultException which has the status code set to 500 (Internal Server Error) and is thrown.
For the methods that have this behavior we have noticed that the whole call chain that generated an exception at some point is retried for a seemingly random number of times, sometimes it's just once, other times 3, 5, even 7 before the control is passed back to the client side and the error message is shown.
The WebService runs in IIS, and if i hook the debugger to it the retry logic doesn't occur anymore probably because VisualStudio halts the execution due to the unhandled exception.
At first this behavior seem'd to point to WS-ReliableMessaging but from the documentation it should be enabled explicitly. Anb we are using a WebHttpBinding, which afaik is not supported.
If I change the Exception behavior to not throw WebFaultException then this behavior stops.
Why is this happening?
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.