dotnetnoob
dotnetnoob

Reputation: 11350

WebException timeout vs HttpWebResponse timeout?

I'm using the Asp.Net WebClient to create an HTTP post.

The below code has try-catch block around the code which catches WebException:

        try
        {
            using (MyWebClient wc = new MyWebClient())
            {
                wc.Headers[HttpRequestHeader.ContentType] = _lender.ContentType;
                wc.Timeout = 200;

                return _lender.GetResult(wc.UploadString(_lender.PostUri, _lender.PostValues));
            }
        }
        catch (WebException ex)
        {
            return new ServiceError(ex.Status.ToString());
        }

The main exceptions I'm looking for are timeouts. I've extended WebClient to allow me to set the timeout.

When I set the timeout to say 100ms, an exception is thrown as expected. I can get the WebException status as per the example (it returns "timeout"), however, I want to return status codes too.

If I extract the httpwebresponse using ex.Response I get a null value returned, when I was expecting an associated status code.

Why do I not get an HttpStatus.Request.Timeout?

Upvotes: 1

Views: 273

Answers (1)

Lutti Coelho
Lutti Coelho

Reputation: 2264

I have the same problem and I realise a few things while I search 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.
}

Upvotes: 1

Related Questions