Stream Socket error handling winRT - c#

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.

Related

SoapException has the same message but in different forms

We have an ASP.NET project. The project is installed via InstallShield. We have a test method that throws SoapException and compares its message:
internal static string ExceptionMsgCheckForConflicts = "Server was unable to process request. ---> Rethrow exception, look at inner exception ---> System.ArgumentException ---> Item is invalid";
internal static string ErrorMsgCheckForConflictsInvalidException = "Exception should start with 'Server was unable to process request. ---> Rethrow exception, look at inner exception ---> System.ArgumentException ---> Item is invalid'";
[Test]
public void ConflictDetectorItemNotAnItemNode()
{
Assert.Throws<SoapException>(() =>
{
try
{
//Some code that throws SoapException
}
catch (SoapException ex)
{
Assert.IsTrue(ex.Message.StartsWith(ExceptionMsgCheckForConflicts, StringComparison.OrdinalIgnoreCase), ErrorMsgCheckForConflictsInvalidException);
throw;
}
});
}
The code works pretty well. But we decided to run this test on the installed version of project. The problem is that in this case exception is thrown with the message:
System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.Exception: Rethrow exception, look at inner exception ---> System.ArgumentException: Item is invalid
In fact it is the same message, but contains the names of exceptions. I and my boss have no idea why this happens.
I'm wondering if the odd try / catch / rethrow is causing the problem. Normally, using NUnit, one doesn't catch the exceptions one is asserting on. A simpler way to write the test would be...
var ex = Assert.Throws<SoapException>(() =>
{
// Code that throws SoapException
}
Assert.That(ex.Message.StartsWith(...));
BTW, I couldn't decide whether this was an answer or a comment, but answers make it easier to format code. :-)

CommunicationException is lifted, even in a try/catch block

I'm currently developping an application for WP7 that needs to make calls to a WCF Service Application. I tested the service with a small WPF application and everything went just fine. But now that I call it from my WP7 app, I systematically get the following exception :
An exception of type 'System.ServiceModel.CommunicationException' occurred in
System.ServiceModel.ni.dll but was not handled in user code
System.ServiceModel.CommunicationException was unhandled by user code
HResult=-2146233087
Message=The remote server returned an error: NotFound.
Source=System.ServiceModel
InnerException: System.Net.WebException
HResult=-2146233079
Message=The remote server returned an error: NotFound.
Source=System.Windows
InnerException: System.Net.WebException
HResult=-2146233079
Message=The remote server returned an error: NotFound.
Source=System.Windows
InnerException:
The exception keeps getting lifted despite the fact I make my service call within a try/catch block like this (in MyProjectPath.Model.User.cs) :
public Task<User> Load(string logon, string pwHash)
{
TaskCompletionSource<User> tcs = new TaskCompletionSource<User>();
client.GetUserByCredsCompleted += ((s, e) =>
{
if (e.Error == null) tcs.TrySetResult(e.Result);
else
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("Error encountered while getting data :");
sb.AppendLine(e.Error.Message);
MessageBox.Show(sb.ToString());
}
});
try
{
client.GetUserByCredsAsync(logon, pwHash);
}
catch (System.ServiceModel.CommunicationException ex)
{
MessageBox.Show(ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return tcs.Task;
}
And when executed, the exception occurs here (in System.ServiceModel.ni.dll) :
public MyProjectPath.ServiceReference.User EndGetUserByCreds(System.IAsyncResult result) {
object[] _args = new object[0];
// Exception gets lifted by the following line :
MyProjectPath.ServiceReference.User _result = ((MyProjectPath.ServiceReference.User)(base.EndInvoke("GetUserByCreds", _args, result)));
return _result;
}
Did anyone already encountered this problem and solved it ? I must admit I'm pretty clueless here...
You're calling an asynchronous API. Although you're wrapping that call in a try/catch block, that call will presumably be starting up a new thread or queueing a request for another existing thread to pick up. Either way, your try/catch is only protecting you against exceptions thrown on the thread which makes the call, and there aren't any. The (start of) your asynchronous call succeeds just fine, so the catch block never comes into effect, and then control is passed to the other thread and this is where the exception is thrown.
You can't protect against exceptions in EndGetUserByCreds by wrapping your call to GetUserByCredsAsync in a try/catch. The two methods are executing at different times different threads. You need to modify EndGetUserByCreds so that it catches exceptions and deals with them appropriately, rather than letting them crash the thread.

SqlClient SqlException not caught

I have a Azure worker role perform simple selects on a SQL Azure database. Rarely it throws the following SqlException.
Log
The underlying provider failed on Open. Inner Exception: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
Exception Type: System.Data.SqlClient.SqlException
The exception is not caught as a SqlException. It is caught in the generic exception handler. Any suggestions as to why that would be?
try{
}
catch(System.Data.SqlClient.SqlException sqlExcep)
{
}
catch(Exception genericExcep)
{
**//The exception is caught as a generic exception**
}
The SQL Database environment is a layer of routers and proxies that handle network load balancing and resource management. If SQL Database itself didn't timeout, then something else in the middle could have (although that's typically rare).
I usually handle IOException errors as well and treat some of them as a form of transient error. What exception type are you actually receiving?
Did you try implementing the Transient Fault Handling Application Block? http://msdn.microsoft.com/en-us/library/hh680934(v=pandp.50)
Herve
Looks like that's the inner exception, not the actual exception you caught. What is the type of the outer exception? The only thing you can do is catch whichever type the caught exception is, and then inspect the inner exception:
try
{
// Stuff
}
catch (Exception exc)
{
if (exc.InnerException is System.Data.SqlClient.SqlException)
{
var sqlException = exc.InnerException as System.Data.SqlClient.SqlException;
// Do stuff with the error.
}
}
The moral of the story is you can't explicitly catch the inner exception :(
Try Microsoft.Data.SqlClient.SqlException instead of System.Data.SqlClient.SqlException
catch (Microsoft.Data.SqlClient.SqlException ex)
{
}

Is the "message" of an exception culturally independent?

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.

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