2

I have a WCF service that is running frequent (1000+) outbound connections per minute to external APIs.

My code throws the following exceptions frequently, but not always showing that is is a WebException with the WebException status property being ReceiveFailure

The code that is making the outbound request is the following:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(paramBuilder.ToString());
request.ServicePoint.ConnectionLeaseTimeout = 0;
request.Method = "GET";
request.Timeout = 33000;    //33 Second Timeout Is By Design
Stream stream = default(Stream);
HttpWebResponse response = default(HttpWebResponse);
try
{

    response = (HttpWebResponse) request.GetResponse();
    stream = response.GetResponseStream();
    reader = new StreamReader(stream,Encoding.UTF8);
    string str = reader.ReadToEnd();
    return str;

}
catch (WebException exception)
{

    //Handle WebException
}
catch (Exception exception)
{
    //Handle Exception
}
finally
{
    if (reader != null)
        reader.Dispose();

    if (response != null)
        response.Close();

    if (stream != null)
        stream.Dispose();
}

The exception stack trace shows that the exception is caused from GetResponse().

What could be causing this to happen that I receive an occasional WebException -ReceiveFailure.

I have already reference the MSDN documentation for this status, but that doesn't help me.

TheJediCowboy
  • 8,924
  • 28
  • 136
  • 208

2 Answers2

2

Shooting in the dark here...

There is a special condition, while waiting for response: if the system clock is being set automatically by the Windows Time service, or manually, you may experience some unpredictable results.

If you're sending your requests over HTTPS, maybe you're facing a regular timeout that was wrongly thrown as a ReceiveFailure.

Check this article for more information: http://support.microsoft.com/kb/2007873

Yaniv
  • 966
  • 12
  • 20
0

I have a related problem and I realise a few things while I was searching for a solution.

  • WebExceptionStatus enum is not equivalent to http status code that the API you call returned. Instead it is a enum of possible error that may occour during a http call.
  • The WebExceptionStatus error code that will be returned when you receive an error (400 to 599) from your API is WebExceptionStatus.ProtocolError aka number 7 as int.
  • When you need to get the response body or the real http status code returned from the api, first you need to check if WebException.Status is WebExceptionStatus.ProtocolError. Then you can get the real response from WebExceptionStatus.Response and read its content.
  • Sometimes the timeout is handled by the caller (aka your code) so you do not have a response in that case. So you can look if WebException.Status is WebExceptionStatus.Timeout

This is an example:

try
{
    ...
}
catch (WebException webException)
{
    if (webException.Status == WebExceptionStatus.ProtocolError)
    {
        var httpResponse = (HttpWebResponse)webException.Response;
        var responseText = "";
        using (var content = new StreamReader(httpResponse.GetResponseStream()))
        {
            responseText = content.ReadToEnd(); // Get response body as text
        }
        int statusCode = (int)httpResponse.StatusCode; // Get the status code
    }
    else if (webException.Status == WebExceptionStatus.ProtocolError)
    {
       // Timeout handled by your code. You do not have a response here.
    }

    // Handle other webException.Status errors. You do not have a response here.
}
Lutti Coelho
  • 2,134
  • 15
  • 31