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
}
Related
I have a socket and I'd like to send messages and read from it.
When I read/write with the socket while the other side is offline, I get the same Exception: System.IO.IOException: Unable to read data from the transport connection: Operation on non-blocking socket would block.
How can I identify in which of the two it happened besides having two separate try-catch blocks? Can't I just get a Timeout Exception when the reading timeout is over?
example:
try
{
SendData("!GetLocation!");
string data = GetData();
}
catch (Exception ex)
{
if (ex is System.IO.IOException)
{
//How can I identify if the exception was raised at the read method or the write method?
}
}
Yeah, exception handling is heavy resource wise, but sometimes is not so bad.
If you stick to only one try-catch you can check the error message.
Note: I have also added a second try-catch for generic (non IO) errors
try
{
SendData("!GetLocation!");
string data = GetData();
}
catch (System.IO.IOException ex)
{
if (ex.Message.IndexOf("Unable to read") != -1)
{
// GetData error
}
else if (ex.Message.IndexOf("Unable to write") != -1)
{
// SendData error
}
else
{
//Other IO errors
}
}
catch(Exception exc)
{
// Unspected errors
}
you could also set a boolean variable and check its value to know where it
broke your code.
bool sendCalled = false;
try
{
SendData("!GetLocation!");
sendCalled = true;
string data = GetData();
}
catch (System.IO.IOException ex)
{
if (sendCalled)
{
// GetData error
}
else
{
// SendData error
}
}
Not that I endorse either of these solutions, but an answer is an answer: you can either
analyze the stack trace of the exception to find out which call failed (e.g. name of the method at the top of the stack frame
set a flag after the write, and do logic based on that flag
Neither of these is as straight forward as wrapping each method call. In fact, wrapping each call conveys your intent. In the catch of your first call, you can return/break/skip the read call, which explicitly tells the reader you're bailing out fast.
I'm incorporating telemetry into my product on all service requests, unfortunately that includes exceptions. A problem I'm having is I surround my requests with a try-catch and if it's successful I log the request and if there's a catch I log the exception than throw the exception so that it still gets propagated up so that it can be debugged. A problem I'm having is that with try-catch I lose all the original data from the original exception caught by my try-catch, which I think would be nice to propagate back up.
public void someFunction(object data)
{
try
{
var response = await request(data);
LogInformation(request: data, response: response);
}
catch (Exception e)
{
throw HandleAndLogException(data, e);
}
}
private HttpResponseException HandleAndLogException(object data, Exception e)
{
LogException(data: data, response: e.Message);
var resp = new HttpResponseMessage(HttpStatusCode.BadRequest) {
Content = new StringContent(e.Message)
};
return new HttpResponseException(resp);
}
So as you can see I create a new HttpResponseException and just append the message to it, but I'd rather propagate back up the exception thrown in it's entirety.
If you want to do something clever/evil, you can use the when keyword to introduce logging without breaking the stack trace on your exception.
See when contextual keyword in the C# reference on MSDN. It's supposed to be used as a filter (the method returns true or false, indicating whether that catch block should be used) but you can do whatever you want with
I think this is what you'd want, although I haven't tested it:
public void someFunction(object data)
{
try
{
var response = await request(data);
LogInformation(request: data, response: response);
}
catch (Exception e) when (HandleAndLogException(data, e))
{
throw;
}
}
private bool HandleAndLogException(object data, Exception e)
{
LogException(data: data, response: e.Message);
return true;
}
I have a method in my program which is a server call back look like this:
private void DeserializerCallback(IAsyncResult aysncResult)
{
HttpWebRequest request = (HttpWebRequest)aysncResult.AsyncState;
HttpWebResponse response;
try
{
response = (HttpWebResponse)request.EndGetResponse(aysncResult);
}
catch(WebException e)
{
VenueMapException venueMapException = new MyException(MyException.ExceptionType.BadResponseException, e);
throw venueMapException;
}
Stream responseStream = response.GetResponseStream();
this.DeserializeStream(responseStream);
}
This method is called after I do this line:
this.MyHttpRequest.BeginGetResponse(new AsyncCallback(this.DeserializerCallback), this.MyHttpRequest);
In the call back method, I throw a exception that defined by myself. Now I want to catch this exception as far from this code as possible, but I am not sure where will the exception go if I do not catch it in this method. Can someone give some suggestion? Thank you
Errors can be caught at Page Level or Application level
Errors can be caught at Application level in the Application_Error
event in Global.asax
http://msdn.microsoft.com/en-us/library/24395wz3.aspx
Errors can be caught at Page Level by the Page_Error event in aspx pages
http://msdn.microsoft.com/en-us/library/24395wz3.aspx
And inside these events we can get the last occured exception by the code
Exception exc = Server.GetLastError();
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
When running the following Java code, I get very accurate and consistent results in determining if the web page I'm testing is up.
protected synchronized boolean checkUrl(HttpURLConnection connection){
boolean error = false;
//HttpURLConnection connection = null;
GregorianCalendar calendar = new GregorianCalendar();
try{
if(connection != null){
connection.connect();
//200 is the expected HTTP_OK response
error = processResponseCode(connection.getResponseCode());
connection.disconnect();
} else{
error = false;
}
}catch(java.net.UnknownHostException uhe){
... }
catch(Exception e){
... }
return error;
}
The closest match to the Java pattern in c# has much higher results of false positives (mostly due to timeouts - which has a default period of 100000ms).
protected bool connectedToUrl = false;
response = null;
HttpWebRequest webreq = (HttpWebRequest)WebRequest.Create(this.getUri());
webreq.Credentials = CredentialCache.DefaultCredentials;
WebResponse res = null;// webreq.GetResponse();
try
{
WebRequest request = WebRequest.Create(this.getUri()) as WebRequest;
request.Credentials = CredentialCache.DefaultCredentials;
if (request != null)
{
// Get response
res = webreq.GetResponse();
connectedToUrl = processResponseCode(res);
}
else
{
logger.Fatal(getFatalMessage());
string error = string.Empty;
}
}
catch (Exception e)
{
throw e;
}
return connectedToUrl;
}
I have tried various patterns in c# to match the effectiveness of the quoted Java code, to no avail.
Any ideas?
I believe this is because you're not closing any of the request objects.
Simply change this:
res = webreq.GetResponse();
connectedToUrl = processResponseCode(res);
to
using (WebResponse res = webreq.GetResponse())
{
connectedToUrl = processResponseCode(res);
}
(Remove the declaration from earlier.)
Until you haven't closed/disposed the response (or it's been finalized), it's holding onto the connection. You can only have a certain number (2 by default, I believe) of connections to any one host at a time, hence the timeouts. When you dispose the response, it allows another request to use the same connection.
Also this:
catch (Exception e)
{
throw e;
}
Does nothing but destroy the stack trace on an exception that's been bubbled upwards. If you have error handling elsewhere in your code I suggest removing the try catch block. Otherwise you should log the exception and move on. Don't just catch it to throw it.
I think you're missing the GregorianCalendar in the C# version :-)
Why do you have two Request Objects in the C# version?