I'm querying a remote server and sometimes get an AggregateException. This is fairly rare and I know how to get around when this happens, but for some reason, it's not entering the catch block whenever the exception is thrown.
This is the code part for the catch block:
try
{
using (Stream stream = await MyQuery(parameters))
using (StreamReader reader = new StreamReader(stream))
{
string content = reader.ReadToEnd();
return content;
}
}
catch (AggregateException exception)
{
exception.Handle((innerException) =>
{
if (innerException is IOException && innerException.InnerException is SocketException)
{
DoSomething();
return true;
}
return false;
});
}
And this is the exception message I'm getting:
System.AggregateException: One or more errors occurred. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
--- End of inner exception stack trace ---
I'm assuming those --> arrows indicate that it's an inner exception right?
So if it's IOException -> SocketException, why is DoSomething() never called?
I suspect you're not actually seeing an AggregateException at this point. There's nothing in the code you have that is doing parallel operations.
If that's correct, you should be able to do something like this:
try
{
using (Stream stream = await MyQuery(parameters))
using (StreamReader reader = new StreamReader(stream))
{
string content = reader.ReadToEnd();
return content;
}
}
catch (IOException exception)
{
if (exception.InnerException is SocketException)
DoSomething();
else
throw;
}
Related
I've got a SOAP request method that returns back a token. For 99% of the time this works fine however 1% of the time I get back a communicationObjectFaultedException.
Is this just unavoidable or is there something in my code that I can improve upon.
MyToken Token = new MyToken ();
Exception exception = null;
bool TokenSet = false;
int attempts = 0;
while(TokenSet == false && attempts <= 2)
{
try
{
MyToken = SSOClient.GenerateSsoToken(id.ToString(), null, null, winframe, null);
TokenSet = true;
exception = null;
}
catch (MessageSecurityException e)
{
exception = e;
SSOClient.Close();
SSOClient = CreateClient();
}
catch(CommunicationObjectFaultedException e)
{
exception = e;
//SSOClient.Close(); can't close what is faulted - I think this is causing some issue once a day or so...
SSOClient = CreateClient();
}
attempts = attempts + 1;
}
The error I get is
System.ServiceModel.CommunicationObjectFaultedException: The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
Server stack trace:
at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at System.ServiceModel.ICommunicationObject.Close(TimeSpan timeout)
at System.ServiceModel.ClientBase`1.System.ServiceModel.ICommunicationObject.Close(TimeSpan timeout)
It's hard to debug and I can't figure out how to manually throw the exception. When I get the exception I just recreate the client and try again, but this doesn't seem to work. Unless it does try again and errors another few times (attempts > 2).
Am I doing something wrong or is this just something that I have to accept.
Attempt 1
So the 2 exceptions both stem from a communication exception and the link says to try and treat them differently depending on the state of the client.
So here we go....
catch (CommunicationException e)
{
exception = e;
if (SSOClient.State != CommunicationState.Faulted)
{
SSOClient.Close();
}
else
{
SSOClient.Abort();
}
SSOClient = CreateClient();
}
I changed the exception cathing to
catch (CommunicationException e)
{
exception = e;
if (SSOClient.State != CommunicationState.Faulted)
{
SSOClient.Close();
}
else
{
SSOClient.Abort();
}
SSOClient = CreateClient();
}
and this resolved the problem.
MessageSecurityException and CommunicationObjectFaultedExceptionboth extend from CommunicationException so makese sense that this catch caught both issues.
You got CommunicationState.Created, closed, opened, faulted.
I had to specifically call SSOClient.Open() to make my code work, just in case this helps someone.
I'm currently receiving a strange error, and want to handle it for 1 specific case. When the server closes and the client is still connected to it, the client will throw an exception
System.Net.Sockets.SocketException: 'An existing connection was
forcibly closed by the remote host'
I know how to handle this, a try and catch, but am I handling more than one reason this exception would be thrown here? I just want to handle it if the server closes, not all of the other reasons this exception may suddenly occur. Can anybody help here?
What line is the error occuring on?
var bytesReceived = _socket.EndReceive(asyncResult);
What method?
private void OnIncomingData(IAsyncResult asyncResult)
Method content
var bytesReceived = _socket.EndReceive(asyncResult);
try
{
var packet = new byte[bytesReceived];
Array.Copy(_buffer, packet, bytesReceived);
var received = Encoding.UTF8.GetString(packet);
CoreUtilities.LogToConsole("Received data: " + received);
}
catch
{
Dispose();
}
finally
{
try
{
_socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, OnIncomingData, _socket);
}
catch
{
}
}
You could handle this using the SocketErrorCode property which part of SocketException. According to this TechNET article (I couldn't find anything on MSDN), the error code should be 10054 which matches with the SocketError.ConnectionReset enum value as shown below:
Example of handling the specific error:
try
{
_socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, OnIncomingData, _socket);
}
catch (SocketException ex)
{
if (ex.SocketErrorCode == SocketError.ConnectionReset)
{
//Do Something
}
}
This issue is really bizarre and has eluded my attempts at debugging. It only occurs when running the app on a Surface tablet. It does not occur on an Asus tablet or while running in Visual Studio. In a particular scenario where Airplane mode has been turned on, a WebException is thrown that I am absolutely unable to catch. I'm not even entirely certain what in my code is causing it to happen, because some of my logging is not happening after a certain point in the code for an unknown reason. I can only assume it's caused by an HttpWebRequest, because of the type of exception being thrown, which appears to be coming from an internal .NET component. Here is the only debugging information I'm able to obtain. It's from the Windows Event Viewer:
Application: <myappname.exe>
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.Net.WebException
Stack:
at System.Net.ServicePoint.ConnectSocketCallback(System.IAsyncResult)
at System.Net.LazyAsyncResult.Complete(IntPtr)
at System.Net.ContextAwareResult.Complete(IntPtr)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(System.Object, IntPtr)
at System.Net.Sockets.Socket.ConnectCallback()
at System.Net.Sockets.Socket.RegisteredWaitCallback(System.Object, Boolean)
at System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(System.Object, Boolean)
I really wish I had more debugging information to provide, but I've tried everything I can think of with tons of try/catch blocks everywhere and logging after most calls--some of which isn't be executed. Does anyone have any clue as to what could be causing this?
EDIT 1:
Based on traces the exception appears to be thrown somewhere in here. Virtually everything is wrapped in a try/catch block, so I can't see how the WebException could possibly be slipping through.
byte[] bytes = Encoding.UTF8.GetBytes(requestXml.ToString());
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "POST";
request.ContentType = "text/xml";
try
{
IAsyncResult requestResult = (IAsyncResult)request.BeginGetRequestStream((rAsyncResult) =>
{
using (Stream uploadStream = request.EndGetRequestStream(rAsyncResult))
{
try
{
uploadStream.Write(bytes, 0, bytes.Length);
uploadStream.Flush();
}
catch (Exception e)
{
// Exception handling
}
finally
{
uploadStream.Dispose();
}
}
IAsyncResult responseResult = (IAsyncResult)request.BeginGetResponse((resAsyncResult) =>
{
try
{
using (HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(resAsyncResult))
{
try
{
data = ProcessResponse(XmlReader.Create(response.GetResponseStream()));
}
catch (Exception e)
{
// Exception handling
}
finally
{
response.Dispose();
}
}
}
catch (WebException e)
{
// Exception handling
}
}, null);
}, null);
}
catch (Exception e)
{
// Exception handling
}
EDIT 2:
I still have not found an acceptable solution. I'm currently checking the connection type before-hand and not allowing the code to continue if it's not connected to WiFi, Mobile, or Ethernet, but that doesn't catch the condition where it's connected to a network that has no Internet connection. WinRT has no solution to check Internet connectivity, and even the method I'm using is unfriendly to work with (it just passes back a number--http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/d8e76732-19d3-47b3-840f-70d87c75ce9f).
Did you try handling the Application.UnhandledException?
Add the event handler to the event in the App class constructor:
public App()
{
// keep the rest of the constructor
this.UnhandledException += OnUnhandledException;
}
In the event handler you can log the exception and mark is handled to prevent the app from closing / crashing:
void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
// log e.Exception details for investigation
e.Handled = true;
}
The issue is probably due to an unhandled exception thrown in your callback; chances are high that the callback is executed asynchronously in a thread different from the one that called the initial request.BeginGetRequestStream and this is why you aren't catching it in the outer try/catch block.
You should be able to overcome this problem by wrapping the entire content of the callback in a try/catch block, that is:
IAsyncResult requestResult = (IAsyncResult)request.BeginGetRequestStream((rAsyncResult) =>
{
try
{
using (Stream uploadStream = request.EndGetRequestStream(rAsyncResult))
{
try
{
uploadStream.Write(bytes, 0, bytes.Length);
uploadStream.Flush();
}
catch (Exception e)
{
// Exception handling
}
finally
{
uploadStream.Dispose();
}
}
IAsyncResult responseResult = (IAsyncResult)request.BeginGetResponse((resAsyncResult) =>
{
try
{
using (HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(resAsyncResult))
{
try
{
data = ProcessResponse(XmlReader.Create(response.GetResponseStream()));
}
catch (Exception e)
{
// Exception handling
}
finally
{
response.Dispose();
}
}
}
catch (WebException e)
{
// Exception handling
}
}, null);
}
catch (Exception ex)
{
// Handle the exception as you wish
}
}, null);
Like Efran Cobisi said EndGetRequestStream is probably the function throwing the exception. Also a using statement will dispose the an object even if there is an exception so no need of a try finally to dispose it.
But in any case you should be using the async methods, that will make the code a lot more readable and exception easier to catch. The equivalent of your code will be:
byte[] bytes = Encoding.UTF8.GetBytes(requestXml.ToString());
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "POST";
request.ContentType = "text/xml";
try
{
using (Stream uploadStream = await request.GetRequestStreamAsync())
{
await uploadStream.WriteAsync(bytes, 0, bytes.Length);
await uploadStream.FlushAsync();
}
using (HttpWebResponse response = (HttpWebResponse) await request.GetRequestStreamAsync())
{
data = ProcessResponse(XmlReader.Create(response.GetResponseStream()));
}
}
catch (Exception e)
{
// Exception
}
There are times that server shutdown, file missing on server and other problem. So, I want to trap or catch the exception thrown by HttpWebRequest when using Dispatcher thread to update content on UI.
The below code is unable to catch error and display in MessageBox.show(). Can anyone show me what I need to do? Thanks
HttpWebRequest webReq;
HttpWebResponse webResp;
public void GetInfo(string Url)
{
webReq = (HttpWebRequest)HttpWebRequest.Create(Url);
try
{
webReq.BeginGetResponse(OnGetBuffer, this);
}
catch (Exception e)
{
}
}
public void OnGetBuffer(IAsyncResult asr)
{
webResp = (HttpWebResponse)webReq.EndGetResponse(asr);
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
Stream streamResult = webResp.GetResponseStream();
try
{
}
catch (Exception)
{
}
});
}
Place a try/catch around the .EndGetResponse() call. I believe this is where the exception is being thrown.
First of all, I hope you don't intend to catch all exceptions and ignore them all. You would be ignoring exceptions that have nothing to do with your network connection failing.
Second, you need to place the try/catch around the code that might throw the exception:
public void OnGetBuffer(IAsyncResult asr)
{
HttpWebResponse webResp;
try
{
webResp = (HttpWebResponse)webReq.EndGetResponse(asr);
}
Catch (WebException ex)
{
// Do something to decide whether to retry, then retry or else
throw; // Re-throw if you're not going to handle the exception
}
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
using (Stream streamResult = webResp.GetResponseStream())
{
// Do something with the stream
}
});
}
try using the WebClient object. Then in the completed event handler the error is returned as e.Error
I have a method that is a listener for a TCP client which looks like this:
private static void ProcessClient(
Object obj)
{
ISession session = (ISession)obj;
NetworkStream networkStream = null;
try
{
DebugUtility.SetThreadName("Worker: {0}", session.Name);
networkStream = session.TcpClient.GetStream();
networkStream.ReadTimeout = Config.ReadTimeout;
// Loop received packets (blocks untill next packet)
Int32 packetSize;
Byte[] buffer = new Byte[session.PacketSize];
while ((packetSize = networkStream.Read(buffer, 0, buffer.Length)) != 0)
{
// Get String from packet bytes
String packet = Encoding.UTF8.GetString(buffer, 0, packetSize);
// Check if packet has data
if (String.IsNullOrEmpty(packet))
continue;
// Log biggest received package
DebugUtility.CheckMaxPacketSize(session.Name, packet.Length);
// Handle packet (in new thread)
Logger.DebugLog("Received: {0}", packet);
ThreadPool.QueueUserWorkItem(session.HandlePacket, packet);
}
}
catch (ObjectDisposedException) { }
catch (NotSupportedException) { }
catch (TimeoutException) { }
catch (SocketException) { }
catch (IOException) { }
catch (Exception ex)
{
Logger.LogException(ex);
}
finally
{
if (networkStream != null)
networkStream.Close();
if (session != null)
session.Disconnect();
}
}
This is for a game service but when I check my logs, I occasionally see this error:
System.Int32 Read(Byte[], Int32, Int32): The stream does not support reading.
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at BusinessLayer.Listener.ListenerWorker.ProcessClient(Object obj) in C:\path\ListenerWorker.cs:line 141 Line: 0
That is the above described file and line 141 is
while ((packetSize = networkStream.Read(buffer,....
Now I have found that NotSupportedException is throwing this error, but why does it go through? Why is it not ignored but does it fall through the normal Exception ex handler?
Edit: Does anyone know how I can invoke this exception? When does it occur? I only see it coming back in my logs to other users, but I don't know when it happens.
Because NetworkStream.Read is throwing an InvalidOperationException, not a NotSupportedException (contrary to the documentation). You can confirm this from Reflector:
if (!this.CanRead)
{
throw new InvalidOperationException(SR.GetString("net_writeonlystream"));
}
Never ever ever swallow an exception unless you are 100% sure that you can do something about it and recover from it. Swallowing all exceptions implies that whatever happens your program can recover and continue. What if it's an OutOfMemoryException or a StackOverflowException, can you program handle those gracefully? Yes log the exception, but for the love of god, rethrow it and let it do its job :)