Handling web server communication feedback with System.Net.WebException in C#

My previous post on sending files via HTTP post did not discuss handling of web server communication feedback. Hence, I will do so in this post.

It is important that a client is able to know if a HTTP request had been successfully processed by the server so that rectification works can be performed.

Errors that can happen in a HTTP session

HTTP is a stateless protocol:

  1. The client sends a HTTP request to the server.
  2. The server process the HTTP request.
  3. The server sends back a HTTP response to the client.

And all these probably takes place in a TCP/IP connection maintained by the client and server. With that in mind, it is not difficult to list some of the errors that can happen in a HTTP session:

  • The web server could not be contacted at all: DNS problems, IP address of machine not reachable, port not opened and etc.
  • The HTTP request is received by the web server but the web server cannot fulfill the HTTP request: 404 File Not Found, 500 Internal Server Error and etc.
  • The web server could be contacted initially but terminates the TCP/IP connection prematurely: uploaded file size limit, web server crashes and etc.
  • The web server could be contacted but the HTTP response returned by the web server was not complete.

Getting the reasons of HTTP communication failure from System.Net.WebException

With the error possibilities in mind, we can proceed with handling them from information given in the System.Net.WebException. Apart from HTTP response with status code 2xx, any other communication feedback will result in a WebException when a HTTP request is sent from the client to the web server. From the Status property defined in the WebException class and the System.Net.WebExceptionStatus enumeration, our client program can decide the kind of rectification works to perform:

try
{
    // Set up the HTTP web request
    HttpWebRequest requestToServer = 
        (HttpWebRequest)WebRequest.Create("http://www.techcoil.com");
    requestToServer.Method = WebRequestMethods.Http.Get;
    requestToServer.Credentials = System.Net.CredentialCache.DefaultCredentials;
                
    // Send the HTTP web request to the server and get the server response
    WebResponse response = requestToServer.GetResponse();
                
    // The following codes will be executed only if a 2xx HTTP response 
    // is received from the server
    StreamReader responseReader = new StreamReader(response.GetResponseStream());
    // Get the response body
    string replyFromServer = responseReader.ReadToEnd();
    Console.WriteLine(replyFromServer);
} 
catch (WebException wex) 
{

    // Exception message and stack trace
    Console.WriteLine(wex.Message);
    Console.WriteLine(wex.StackTrace);

    // Inspect the reason of communication failure
    switch (wex.Status)
    {
        case WebExceptionStatus.ConnectFailure:
            // handle failure to connect to server
            break;

        case WebExceptionStatus.ReceiveFailure:
            // handle failure to receive complete
            // HTTP response from server
            break;

        case WebExceptionStatus.Timeout:
            // handle timeout when waiting for
            // HTTP response from server
            break;

        case WebExceptionStatus.ConnectionClosed:
            // handle connection with server closed 
            // prematurely
            break;

        // This is where we can examine HTTP status
        // codes other than 2xx and the server response 
        // body
        case WebExceptionStatus.ProtocolError:
            // Examine the HTTP response returned
            HttpWebResponse response = (HttpWebResponse)wex.Response;
            StreamReader responseReader = 
                new StreamReader(response.GetResponseStream());
            string responseFromServer = responseReader.ReadToEnd();
            switch (response.StatusCode)
            {
                case HttpStatusCode.BadRequest:
                    // handle bad request (http status code 400)
                    break;
                case HttpStatusCode.InternalServerError:
                    // handle internal server error (http status code 500)
                    break;
                default:
                    // handle other http status code returned by
                    // the server.
                    break;
            } // end switch(res.StatusCode)
            response.Close();
            break;

        case WebExceptionStatus.NameResolutionFailure:
            // handle DNS error
            break;

        default:
            // handle other errors not in this switch statement
            break;
    } // end switch(wex.Status)
} // end try-catch

Related posts

About Clivant

Clivant a.k.a Chai Heng enjoys composing software and building systems to serve people. He owns techcoil.com and hopes that whatever he had written and built so far had benefited people. All views expressed belongs to him and are not representative of the company that he works/worked for.