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:
- The client sends a HTTP request to the server.
- The server process the HTTP request.
- 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