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.
User contributions licensed under CC BY-SA 3.0