1

My app produces the following error randomly. I havent been able to re-produce it on my machine, but on users who have installed it, it happens to them.

System.Net.WebException: The request was aborted: The request was canceled.
   at System.Net.ConnectStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   at System.IO.StreamReader.ReadBuffer()
   at System.IO.StreamReader.ReadToEnd()

Whats odd is, ReadToEnd() cant product a WebException error (Found out by hovering over it and seeing what type of exceptions it can cause), yet from this Crash Dump it is?, To make sure I even put a WebException try catch and it still happens.

I read online a tiny bit and see it might be caused by ServicePointManager.DefaultConnectionLimit so I added that in with 1000 int value, and now im not sure if it fixed it - I havent seen any reports, but that doesnt mean its not happening.

using (HttpWebResponse resp = (HttpWebResponse)r.GetResponse())
using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
{
    string s = "";
    try { s = sr.ReadToEnd(); }
    catch (IOException) { return "2"; }
    catch (WebException) { return "2"; }
}

This is the code im using, if needed, I can provide r's values. Just know that I use quite a lot.


EDIT: I can confirm on the client's side that even with the ServicePointManager.DefaultConnectionLimit set to 1000 it still occurs.

user7842865
  • 51
  • 1
  • 8
  • Check the client side if it send request with timeout then probably that timeout was reached – Samvel Petrosov Jul 08 '17 at 16:01
  • There are all kind of reasons that the socket throws that exception: firewalls, wifi/network disconnects, network latency. There is not much you can do about that, except handling that condition. For example retry the call once. – rene Jul 08 '17 at 16:03
  • @rene How would I retry something that I dont know whats being caused or how to catch it in the first place. – user7842865 Jul 08 '17 at 16:58
  • The point is: you'll never be able to enumerate all possible causes for how that code will fail, nor can you control the failure conditions. At best you catch the exception and the retry that same action again for a couple of times until you let it fail completely, see https://stackoverflow.com/questions/1563191/cleanest-way-to-write-retry-logic – rene Jul 08 '17 at 17:44
  • @rene I know, thats why im trying to find out how to catch it - its coming from sr.ReadToEnd() as a WebException yet sr.ReadToEnd() doesnt do a WebException, so where am I meant to do a Try Catch? – user7842865 Jul 08 '17 at 18:37
  • Well, somewhere up your call stack where you have all the context and values needed to retry the complete call. And that would be the place where you catch that exception, not at the level you do it now. But nobody here can advise you any further because you didn't share that part. You might find the articles about exception handling from Eric Lippert useful: https://ericlippert.com/category/exception-handling/ – rene Jul 08 '17 at 19:27

2 Answers2

0

I had a similar problem to this some time ago. Can you handle the WexException doing something like this:

public static HttpWebResponse GetHttpResponse(this HttpWebRequest request)
{
    try
    {
        return (HttpWebResponse) request.GetResponse();
    }
    catch (WebException ex)
    {
        if(ex.Response == null || ex.Status != WebExceptionStatus.ProtocolError)
            throw; 

        return (HttpWebResponse)ex.Response;
    }
}

I borrowed the code above from the answerer here: HttpWebRequest.GetResponse throws WebException on HTTP 304

Then the first line of your code would do this:

using (HttpWebResponse resp = GetHttpResponse(r))
w0051977
  • 15,099
  • 32
  • 152
  • 329
  • Wait does that code make all HTTP Status Codes not go into the Catch of Try Catch (Not impose an exception)? If so thats actually really handy.EDIT: but no I dont think that will help in my case as it turns out its to do with the StreamReader and not so much the Response (I dont think) – user7842865 Jul 08 '17 at 16:36
  • All requests will enter the GetHttpResponse. The catch clause is only reached if a WebException occurs. Then you can handle it. – w0051977 Jul 08 '17 at 16:38
  • Why is the catch returning ex.Response? what does that do exactly? – user7842865 Jul 08 '17 at 16:51
  • @user7842865, Please see this: https://msdn.microsoft.com/en-us/library/system.net.webexception.response(v=vs.110).aspx – w0051977 Jul 08 '17 at 16:54
  • ohh ok, but I want to be able to return back ProtocolError related responses, would this still return it? – user7842865 Jul 08 '17 at 16:57
  • If the WebException Status equals WebExceptionStatus.ProtocolError i.e. protocol error, then it should produce a response. – w0051977 Jul 08 '17 at 17:06
  • Right but since ProtocolErrors return as an Exception, the try catch with grab it, but will only either throw, or return the Exceptions response, which isnt the same the the Requests Response or is it? Never usually use ex.Response. – user7842865 Jul 08 '17 at 17:07
  • You could handle the response e.g. try connecting again. – w0051977 Jul 08 '17 at 17:27
  • Ok well I tested and can confirm this makes no difference, it really does seem to be related to the sr.ReadToEnd – user7842865 Jul 08 '17 at 18:30
  • Please see L.Bs answer to this question: https://stackoverflow.com/questions/11828843/webexception-how-to-get-whole-response-with-a-body. It may help you. – w0051977 Jul 08 '17 at 18:45
  • How does using JSON to Deserialize the ReadToEnd help? If an exception is occuring when getting ReadToEnd, wouldnt it fail to actually start Deserializing? – user7842865 Jul 08 '17 at 18:49
  • What exactly are you trying to do please? Do you want t handle the exception? – w0051977 Jul 08 '17 at 18:54
0

Found out what managed to fix it, no idea WHY, but this works:

try
{
    using (HttpWebResponse resp = httpparse.response(r))
    {
        if(resp != null)
        {
            using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
            {
                string s = "";
                try { s = sr.ReadToEnd(); }
                catch (IOException) { return "2"; }
            }
        } else
        {
            return "2";
        }
    }
}
catch (WebException)
{
    return "2";
}

Makes no sense, the error occurs at sr.ReadToEnd(), yet putting the Try Catch over the response() makes it fixed?

user7842865
  • 51
  • 1
  • 8