Is the "message" of an exception culturally independent? - c#

In an application I'm developing, I have the need to handle a socket-timeout differently from a general socket exception. The problem is that many different issues result in a SocketException and I need to know what the cause was.
There is no inner exception reported, so the only information I have to work with is the message:
"A connection attempt failed because the connected party did not
properly respond after a period of time, or established connection
failed because connected host has failed to respond"
This question has a general and specific part:
is it acceptable to write conditional logic based upon the textual representation of an exception?
Is there a way to avoid needing exception handling?
Example code below...
try
{
IPEndPoint endPoint = null;
client.Client.ReceiveTimeout = 1000;
bytes = client.Receive(ref endPoint);
}
catch( SocketException se )
{
if ( se.Message.Contains("did not properly respond after a period of time") )
{
// Handle timeout differently..
}
}
I'm wanting to cease the "wait for new data" every now and again, so that my worker thread can look to see whether it has been asked to gracefully close - I would rather avoid cross-thread termination of the socket to provide this mechanism.

of course it is! there are more descriptive fields in SocketException, you should not perform string comparison. http://msdn.microsoft.com/library/system.net.sockets.socketexception_members.aspx, especially:
ErrorCode
NativeErrorCode
SocketErrorCode

Exceptions are Culture relevant, I have "German" exception messages.
Use the SocketErrorCode.

Related

HTTP 1.1 protocol read-line error from server

I am sending a message to a server through HTTP 1.1. Everything sends correctly to the server or website I have chosen, but when I receive the response from the server/website and my sr.readToEnd() executes, it terminates.
I know that the message I have sent is correct, but I am trying to do a try-catch statement were if it terminates again, it will try to read another way. I am not sure how to do this and I was advised that I could use content-length (except I do not know how to do that either).
Here is what I have so far:
try
{ //Read server message
String response = sr.ReadToEnd();
}
catch
{ //If terminate occurs, read a different way
}
If I remove the try/catch blocks I see this:
Unhandled Exception: System.IO.IOException: Unable to read data from the transport connection: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time..
I know it's pretty brief what I provided, but any methods to tackle this sort of problem I described?
I'd say in general you can do (as #joel recommended.
Or try whether catch when() works for you.
Example:
try
{
someCode();
}
catch (YourExpectedException ex) when (
someBooleanExpression
|| someOtherBooleanExpr
|| thirdBoolean)
{
/* this part runs when() YourExpectedException occurs *and*
one of those three hypothetical example expressions is True */
}
catch (YourExpectedException ex)
{
/* this part runs If YourExpectedException occurs and the previous
When() expression is *Not true */
Whatever();
} /* you can continue catching other expected exceptions
and when() combinations here.
And/Or perhaps say any other exception is unexpected and
will be handled by a higher-level:
*/
catch // any other Exception just to re-throw it back 'to-whom-it-may-concern':
throw;
See also Catching exceptions with "catch, when"

Stream Socket error handling winRT

I am working on stream socket,
According to msdn documentaion:
Handling exceptions
You must write code to handle exceptions when you call asynchronous methods on the StreamSocket class. Exceptions can result from parameter validation errors, name resolutions failures, and network errors. Exceptions from network errors (loss of connectivity, connection failures, and server failures, for example) can happen at any time. These errors result in exceptions being thrown. If not handled by your app, an exception can cause your entire app to be terminated by the runtime.
The Windows.Networking.Sockets namespace has features that simplify handling errors when using sockets. The GetStatus method on the SocketError class can convert the HRESULT from an exception to a SocketErrorStatus enumeration value. This can be useful for handling specific network exceptions differently in your app. An app can also use the HRESULT from the exception on parameter validation errors to learn more detailed information on the error that caused the exception.
So I have used following code to handle socket connect error states.
try
{
var socket = new StreamSocket();
HostName host = new HostName("www.google.com");
// connection is executed synchronously
socket.ConnectAsync(host, "2000", SocketProtectionLevel.PlainSocket).AsTask().Wait();
Debug.WriteLine("Success");
}
catch (Exception ex)
{
SocketErrorStatus socketErrorStatus = SocketError.GetStatus(ex.HResult);
switch(socketErrorStatus)
{
case SocketErrorStatus.ConnectionTimedOut:
//do something
break;
case SocketErrorStatus.HostNotFound:
//do something
break;
default:
break;
}
}
But the exception object returned on socket error doesn't contain valid HResult.
Following is resultant exception object:
Count = The name 'InnerExceptionCount' does not exist in the current context
[System.AggregateException]: Count = The name 'InnerExceptionCount' does not exist in the current context
Data: {System.Collections.ListDictionaryInternal}
HelpLink: null
HResult: -2146233088
InnerException: {System.Exception: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. (Exception from HRESULT: 0x8007274C)}
Message: "One or more errors occurred."
Source: "mscorlib"
StackTrace: " at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)\r\n at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)\r\n at System.Threading.Tasks.Task.Wait()\r\n at StreamSokcetSample.MainPage.Button_Tapped(Object sender, TappedRoutedEventArgs e)"
In this situation I am always getting SocketErrorStatus.Unknown(default value) as result whereas when I pass int value of HRESULT: 0x8007274C to GetStatus, it results in correct output(ConnectionTimedOut = 3).
InnerException: {System.Exception: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. (Exception from HRESULT: 0x8007274C)}
Can I rely upon inner exception message and fetch HRESULT from there?
Is there any other way to get desired results?
You are getting an AggregateException since it's being generated from an async method
So yes, you have to check the HResult of InnerException
SocketErrorStatus socketErrorStatus = SocketError.GetStatus(ex.InnerException.HResult);
This will give you desired output.
The root exception is an AggregateException (it is an .NET level exception), it is usually a wrapper exception for exception thrown from another thread. In this case, it is because you used the "ConnectAsync" method which was running in thread pool.
So to get the correct socket status, you should use the InnerException which is throw from the Windows Runtime level.

The I/O operation has been aborted because of either a thread exit or an application request

My application is working as a client application for a bank server. The application is sending a request and getting a response from the bank. This application is normally working fine, but sometimes
The I/O operation has been aborted because of either a thread exit or
an application request
error with error code as 995 comes through.
public void OnDataReceived(IAsyncResult asyn)
{
BLCommonFunctions.WriteLogger(0, "In :- OnDataReceived",
ref swReceivedLogWriter, strLogPath, 0);
try
{
SocketPacket theSockId = (SocketPacket)asyn.AsyncState;
int iRx = theSockId.thisSocket.EndReceive(asyn); //Here error is coming
string strHEX = BLCommonFunctions.ByteArrToHex(theSockId.dataBuffer);
}
}
Once this error starts to come for all transactions after that same error begin to appear, so
please help me to sort out this problem. If possible then with some sample code
Regards,
Ashish Khandelwal
995 is an error reported by the IO Completion Port. The error comes since you try to continue read from the socket when it has most likely been closed.
Receiving 0 bytes from EndRecieve means that the socket has been closed, as does most exceptions that EndRecieve will throw.
You need to start dealing with those situations.
Never ever ignore exceptions, they are thrown for a reason.
Update
There is nothing that says that the server does anything wrong. A connection can be lost for a lot of reasons such as idle connection being closed by a switch/router/firewall, shaky network, bad cables etc.
What I'm saying is that you MUST handle disconnections. The proper way of doing so is to dispose the socket and try to connect a new one at certain intervals.
As for the receive callback a more proper way of handling it is something like this (semi pseudo code):
public void OnDataReceived(IAsyncResult asyn)
{
BLCommonFunctions.WriteLogger(0, "In :- OnDataReceived", ref swReceivedLogWriter, strLogPath, 0);
try
{
SocketPacket client = (SocketPacket)asyn.AsyncState;
int bytesReceived = client.thisSocket.EndReceive(asyn); //Here error is coming
if (bytesReceived == 0)
{
HandleDisconnect(client);
return;
}
}
catch (Exception err)
{
HandleDisconnect(client);
}
try
{
string strHEX = BLCommonFunctions.ByteArrToHex(theSockId.dataBuffer);
//do your handling here
}
catch (Exception err)
{
// Your logic threw an exception. handle it accordinhly
}
try
{
client.thisSocket.BeginRecieve(.. all parameters ..);
}
catch (Exception err)
{
HandleDisconnect(client);
}
}
the reason to why I'm using three catch blocks is simply because the logic for the middle one is different from the other two. Exceptions from BeginReceive/EndReceive usually indicates socket disconnection while exceptions from your logic should not stop the socket receiving.
In my case, the request was getting timed out. So all you need to do is to increase the time out while creating the HttpClient.
HttpClient client = new HttpClient();
client.Timeout = TimeSpan.FromMinutes(5);
I had the same issue with RS232 communication. The reason, is that your program executes much faster than the comport (or slow serial communication).
To fix it, I had to check if the IAsyncResult.IsCompleted==true. If not completed, then IAsyncResult.AsyncWaitHandle.WaitOne()
Like this :
Stream s = this.GetStream();
IAsyncResult ar = s.BeginWrite(data, 0, data.Length, SendAsync, state);
if (!ar.IsCompleted)
ar.AsyncWaitHandle.WaitOne();
Most of the time, ar.IsCompleted will be true.
I had this problem. I think that it was caused by the socket getting opened and no data arriving within a short time after the open. I was reading from a serial to ethernet box called a Devicemaster. I changed the Devicemaster port setting from "connect always" to "connect on data" and the problem disappeared. I have great respect for Hans Passant but I do not agree that this is an error code that you can easily solve by scrutinizing code.
In my case the issue was caused by the fact that starting from .NET 5 or 6 you must either call async methods for async stream, or sync methods for sync strem.
So that if I called FlushAsync I must have get context using GetContextAsync
What I do when it happens is Disable the COM port into the Device Manager and Enable it again.
It stop the communications with another program or thread and become free for you.
I hope this works for you. Regards.
I ran into this error while using Entity Framework Core with Azure Sql Server running in Debug mode in Visual Studio. I figured out that it is an exception, but not a problem. EF is written to handle this exception gracefully and complete the work. I had VS set to break on all exceptions, so it did. Once I unchecked the check box in VS to not break on this exception, my C# code, calling EF, using Azure Sql worked every time.

Exception in "using" statement with WCF not closing connections properly. How does one close faulted WCF client connections or those with exceptions?

There are several questions on StackOverflow regarding closing WCF connections, however the highest ranking answers refers to this blog:
http://marcgravell.blogspot.com/2008/11/dontdontuse-using.html
I have a problem with this technique when I set a breakpoint at the server and let the client hang for more than one minute. (I'm intentionally creating a timeout exception)
The issue is that the client appears to "hang" until the server is done processing. My guess is that everything is being cleaned up post-exception.
In regard to the TimeOutException it appears that the retry() logic of the client will continue to resubmit the query to the server over and over again, where I can see the server-side debugger queue up the requests and then execute each queued request concurrently. My code wan't expecting WCF to act this way and may be the cause of data corruption issues I'm seeing.
Something doesn't totally add up with this solution.
What is the all-encompassing modern way
of dealing with faults and exceptions
in a WCF proxy?
Update
Admittedly, this is a bit of mundane code to write. I currently prefer this linked answer, and don't see any "hacks" in that code that may cause issues down the road.
This is Microsoft's recommended way to handle WCF client calls:
For more detail see: Expected Exceptions
try
{
...
double result = client.Add(value1, value2);
...
client.Close();
}
catch (TimeoutException exception)
{
Console.WriteLine("Got {0}", exception.GetType());
client.Abort();
}
catch (CommunicationException exception)
{
Console.WriteLine("Got {0}", exception.GetType());
client.Abort();
}
Additional information
So many people seem to be asking this question on WCF that Microsoft even created a dedicated sample to demonstrate how to handle exceptions:
c:\WF_WCF_Samples\WCF\Basic\Client\ExpectedExceptions\CS\client
Download the sample:
C# or VB
Considering that there are so many issues involving the using statement, (heated?) Internal discussions and threads on this issue, I'm not going to waste my time trying to become a code cowboy and find a cleaner way. I'll just suck it up, and implement WCF clients this verbose (yet trusted) way for my server applications.
Optional Additional Failures to catch
Many exceptions derive from CommunicationException and I don't think most of those exceptions should be retried. I drudged through each exception on MSDN and found a short list of retry-able exceptions (in addition to TimeOutException above). Do let me know if I missed an exception that should be retried.
Exception mostRecentEx = null;
for(int i=0; i<5; i++) // Attempt a maximum of 5 times
{
try
{
...
double result = client.Add(value1, value2);
...
client.Close();
}
// The following is typically thrown on the client when a channel is terminated due to the server closing the connection.
catch (ChannelTerminatedException cte)
{
mostRecentEx = cte;
secureSecretService.Abort();
// delay (backoff) and retry
Thread.Sleep(1000 * (i + 1));
}
// The following is thrown when a remote endpoint could not be found or reached. The endpoint may not be found or
// reachable because the remote endpoint is down, the remote endpoint is unreachable, or because the remote network is unreachable.
catch (EndpointNotFoundException enfe)
{
mostRecentEx = enfe;
secureSecretService.Abort();
// delay (backoff) and retry
Thread.Sleep(1000 * (i + 1));
}
// The following exception that is thrown when a server is too busy to accept a message.
catch (ServerTooBusyException stbe)
{
mostRecentEx = stbe;
secureSecretService.Abort();
// delay (backoff) and retry
Thread.Sleep(1000 * (i + 1));
}
catch(Exception ex)
{
throw ex; // rethrow any other exception not defined here
}
}
if (mostRecentEx != null)
{
throw new Exception("WCF call failed after 5 retries.", mostRecentEx );
}
Closing and Disposing a WCF Service
As that post alludes to, you Close when there were no exceptions and you Abort when there are errors. Dispose and thus Using shouldn't be used with WCF.

Does TcpListener.AcceptTcpClient throw uncritical exceptions?

In my application, I currently stop listening when AcceptTcpClient (or EndAcceptTcpClient) throws an exception. Typically exceptions are thrown when I stop the listener (socket error 10004) or when I disconnect the network adapter.
try
{
while (true)
{
TcpClient client = listener.AcceptTcpClient();
// omitted: start new thread which handles the client connection
}
}
catch (...)
{
// omitted: handle exception, log, stop listening
}
But, are there any exceptions that are caused by the client, and would require to ignore (or log) the exception and continue calling AcceptTcpClient?
MSDN has documentation that will list all exceptions that can be thrown by methods/members/etc.
I find it easy to get where you want to go by searching google for something like "MSDN Ssystem.Net.Sockets.TcpListener class" and then navigating to the page I need.
TcpLisenter.AcceptTcpClient Method
MSDN lists 2 exceptions that can be thrown.
InvalidOperationException : The listener has not been started with a call to Start.
SocketException : Use the SocketException.ErrorCode property to obtain the specific error code. When you have obtained this code, you can refer to the Windows Sockets version 2 API error code documentation in MSDN for a detailed description of the error.

Categories