Error Handling for WebRequest & Response - c#

I am currently running a method that takes a string (a domain name) and checks to see if the site is available or not and passes the information into a Domain object I have created. Currently, I am running into an issue where one of the sites is down and is in turn crashing the application. Below is the method:
private Domain GetStatus(string x)
{
string status = "";
WebRequest req = HttpWebRequest.Create("http://www." + x);
WebResponse res = req.GetResponse();
HttpWebResponse response = (HttpWebResponse)res;
if ((int)response.StatusCode > 226 || response.StatusCode == HttpStatusCode.NotFound)
{
status = "ERROR: " + response.StatusCode.ToString();
}
else
{
status = "LIVE";
}
Domain temp = new Domain(x, status);
return temp;
}
Initial thoughts were that the response.StatusCode == HttpStatusCode.NotFound would handle such an error but it is currently crashing on the line WebResponse res = req.GetResponse(); with the following response:
System.Net.WebException: 'The remote name could not be resolved: 'www.DOMAIN.com''

The issue is due to the fact that your own code is raising an exception.
This can be due to the lack of an internet connection, or a dns resolve issue (which could be caused by the remote party).
So, if the remote server throws an error, you'll get HTTP 500 Internal Server Error, if you can't reach it; your code throws an exception and you'll need to handle that.
To fix this, you can use a try/catch block, something like this:
private Domain GetStatus(string x)
{
string status = "";
try
{
WebRequest req = HttpWebRequest.Create("http://www." + x);
WebResponse res = req.GetResponse();
HttpWebResponse response = (HttpWebResponse)res;
if ((int)response.StatusCode > 226 ||
response.StatusCode == HttpStatusCode.NotFound)
{
status = "ERROR: " + response.StatusCode.ToString();
}
else
{
status = "LIVE";
}
}
catch (Exception e)
{
status = "ERROR: Something bad happend: " + e.ToString();
}
Domain temp = new Domain(x, status);
return temp;
}
By the way, the message,
The remote name could not be resolved
indicates that the host cannot be resolved.
Most likely cause is that your internet is down or, the domain is misspelled or the route to the domain is faulty (e.g. on intranet environments).

HttpWebRequest is all about HTTP protocol, which is kind of a agreed upon language.
But if the person on the other end doesn't exists, so how should you expect him to return you an "Hello" for example ?
So StatusCode is really just about if the actual remote site did response, what did the response state was according to the request resource, is it Successful(200) ? Not Found(404) ? Unauthorized(401) and so on.
Exception means, i couldn't reach the site because of many reasons.
StatusCode means the resource you requested has return this response type.
But a more actual check if the site is alive or not, is querying a static page and not getting exception, a more healthy check, will querying a static page, you will always count as being Healthy; meaning will return a 200 OK response.
So it all depends on what LIVE means for you (or the client using it).
Is it the remote host is actually receiving requests, meaning no Exceptions.
Or it actually means, he's able to get requests and returning me a valid StatusCode response that i expect him to return (Healthy).

Related

WebRequest Strange NotFound Error

I have 2 different ASP.NET Core websites: admin and public.
Both running on staging server and on local machine.
I send GET request to different pages to determine execution time of different pages and encountered problem with admin site: all urls on local instance and staging always returns 404 error:
An unhandled exception of type 'System.Net.WebException' occurred in
System.dll
Additional information: The remote server returned an error: (404) Not
Found.
Meanwhile, same requests in browser return html pages normally. Requests through HttpWebRequest to public site always also return 200 Status Code (OK).
Code for request I took here.
I tried to add all headers and cookies from browser request, but it didn't help. Also tried to debug local instance and found that no exceptions thrown while request executed.
Any ideas?
404 is way to generic. The code provided in answer in your link (https://stackoverflow.com/a/16642279/571203) does no error handling - this is brilliant example of how you can get to troubles when you blindly copy code from stackoverflow :)
Modified code with error handling should look like:
string urlAddress = "http://google.com/rrr";
var request = (HttpWebRequest)WebRequest.Create(urlAddress);
string data = null;
string errorData = null;
try
{
using (var response = (HttpWebResponse)request.GetResponse())
{
data = ReadResponse(response);
}
}
catch (WebException exception)
{
using (var response = (HttpWebResponse)exception.Response)
{
errorData = ReadResponse(response);
}
}
static string ReadResponse(HttpWebResponse response)
{
if (response.CharacterSet == null)
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
return reader.ReadToEnd();
}
}
using (var reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(response.CharacterSet)))
{
return reader.ReadToEnd();
}
}
So when there is an exception, you'll get not just the status code, but entire response from server in the errorData variable.
One thing to check is proxy - browser can use http proxy while your server client uses none.

HttpWebRequest.GetResponse methods throws 404 exception

I want to download one image from url using console application.
I have used following code:
string sourceUrl = "http://i.ytimg.com/vi/pvBnYBsUi9A/default.jpg"; // Not Found
//string sourceUrl = "http://i.ytimg.com/vi/OrxZAN1FZUY/default.jpg"; // Found
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(sourceUrl);
HttpWebResponse response = null;
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (Exception)
{
}
Above code throws exception in line "response = (HttpWebResponse)request.GetResponse();"
but when I am accessing "http://i.ytimg.com/vi/pvBnYBsUi9A/default.jpg" url in my browser then image will be display.
What I am missing here?
I tried that url "http://i.ytimg.com/vi/pvBnYBsUi9A/default.jpg" in Chrome
developer tools. It also receives a 404, but the response includes the image, which displays.
Your code is not the cause of the exception. The site is returning a 404 and your code gets an exception.
You could write logic to look at the response even if you get a 404 and decide whether to take it anyway, as the browser does.
It looks like you can get the response returned by the site if you catch WebException, which allows you to see the http request status and the response, per the documentation.
Example from the .Net 4.5 doc...
try
{
// Creates an HttpWebRequest for the specified URL.
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url);
// Sends the HttpWebRequest and waits for a response.
HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
if (myHttpWebResponse.StatusCode == HttpStatusCode.OK)
Console.WriteLine("\r\nResponse Status Code is OK and StatusDescription is: {0}",
myHttpWebResponse.StatusDescription);
// Releases the resources of the response.
myHttpWebResponse.Close();
}
catch(WebException e)
{
Console.WriteLine("\r\nWebException Raised. The following error occured : {0}",e.Status);
}
catch(Exception e)
{
Console.WriteLine("\nThe following Exception was raised : {0}",e.Message);
WebException has Response and Status properties. So it looks like the .Net way to deal with this is to catch WebException and determine how to handle based on the status and response content (if necessary).

RestSharp + Server Down - How do you know if server is down?

I am wondering how can I check if the RestSharp request I made failed because the server is down vs something else.
When I shutdown my server I get a status code of "NotFound" but that could be a particular record was not found(which I do on my site if say they try to find a record that might be recently deleted).
How can I figure out the server is actually down?
Edit
here is my code
private readonly RestClient client = new RestClient(GlobalVariables.ApiUrl);
var request = new RestRequest("MyController", Method.POST);
request.AddParameter("UserId", "1");
request.AddParameter("Name", name.Trim());
var asyncHandle = client.ExecuteAsync(request, response =>
{
var status = response.StatusCode;
});
When the server is down, it should not return a "404 NotFound" error.
The most appropriate in this case is HTTP Error 503 - Service unavailable
The Web server (running the Web site) is currently unable to handle
the HTTP request due to a temporary overloading or maintenance of the
server. The implication is that this is a temporary condition which
will be alleviated after some delay. Some servers in this state may
also simply refuse the socket connection, in which case a different
error may be generated because the socket creation timed out.
That way checking that RestResponse.StatusCode is 503 it will tell you that the server is down.
I am having the same issue.
I decided to check for the ContentLength too. At least my webservice always returns ContentLength>0 (even for NotFound occurrences). This seems to work out.
if ( response.StatusCode == System.Net.HttpStatusCode.NotFound &&
response.ContentLength == -1 ){
==> client couldn't connect to webservice
}
In my scenario, I needed to check if anything happened to the connection, e.g. connection time out, can't resolve the host name, etc. So I also added following code:
try
{
var client = new RestClient(_configuration.ServerUrl);
var request = new RestRequest
{
Resource = _configuration.SomeUrl,
Method = Method.POST
};
var response = client.Execute(request);
if (response.ErrorException != null)
{
throw response.ErrorException;
}
}
catch (WebException ex)
{
// TODO: check ex.Status, if it matches one of needed conditions.
}
For more information about WebExceptionStatus Enumeration, please, see following link https://msdn.microsoft.com/en-us/library/system.net.webexceptionstatus(v=vs.110).aspx

Consuming Twitters 1.1 API using OAuth, getting no response and it happens instantly

I am trying to swap my website over to consuming the new Twitter 1.1 API with uses OAuth 1.0a. I am able to get the correct response using a REST client and I am now trying to duplicate that on my website using c#.
I have constructed my headers the appropriate way and I have verified that they are in the correct format for what Twitter is looking for.
The issue I am having is that I do not think I am actually sending the request. I say this because my application returns almost instantly. The request should take a second or so to send at least, and my response has totally empty, with no 401 or 400 status code.
Below I have the code that actually sends the request. I am actually sending the request and if so why am I not getting any status code or anything.
Thanks in advance for the help.
//string url = "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=MYSCREENNAME&count=2";
string url = "https://api.twitter.com/1.1/statuses/user_timeline.json";
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Method = "GET";
webRequest.Headers.Add("Authorization", authorizationHeaderParams);
try {
var response = webRequest.GetResponse() as HttpWebResponse;
if (response != null && response.StatusCode != HttpStatusCode.OK) {
lblresponse.InnerText = "The request did not complete and returned status code: {0} " + response.StatusCode;
}
if (response != null) {
var reader = new StreamReader(response.GetResponseStream());
reader.ReadToEnd();
lblresponse.InnerText += "success";
}
} catch {
lblresponse.InnerText += "fail";
}
So yeah this code goes straight to the catch block. My thoughts are I am not actually sending the request, since it takes no time to happen. I know there are some libraries designed to make this easier but I would much rather learn how to do it myself (with the help of you guys).
Thanks.
The request is going to throw an exception in the case of a 400 or 401. So catch System.Web.Exception in the catch block to see if there's a 400 or 401.
catch(System.Web.Exception ex) {
var errorReponse = (HttpWebResponse)ex.Response;
var statusCode = errorReponse.StatusCode;
lblresponse.InnerText += "fail";
}

Test if a URI is up

I'm trying to make a simple app that will "ping" a uri and tell me if its responding or not
I have the following code but it only seems to check domains at the root level
ie www.google.com and not www.google.com/voice
private bool WebsiteUp(string path)
{
bool status = false;
try
{
Uri uri = new Uri(path);
WebRequest request = WebRequest.Create(uri);
request.Timeout = 3000;
WebResponse response;
response = request.GetResponse();
if (response.Headers != null)
{
status = true;
}
}
catch (Exception loi)
{
return false;
}
return status;
}
Is there any existing code out there that would better fit this need?
Edit: Actually, I tell a lie - by default 404 should cause a web exception anyway, and I've just confirmed this in case I was misremembering. While the code given in the example is leaky, it should still work. Puzzling, but I'll leave this answer here for the better safety with the response object.
The problem with the code you have, is that while it is indeed checking the precise URI given, it considers 404, 500, 200 etc. as equally "successful". It also is a bit wasteful in using GET to do a job HEAD suffices for. It should really clean up that WebResponse too. And the term path is a silly parameter name for something that isn't just a path, while we're at it.
private bool WebsiteUp(string uri)
{
try
{
WebRequest request = WebRequest.Create(uri);
request.Timeout = 3000;
request.Method = "HEAD";
using(WebResponse response = request.GetResponse())
{
HttpWebResponse hRes = response as HttpWebResponse;
if(hRes == null)
throw new ArgumentException("Not an HTTP or HTTPS request"); // you may want to have this specifically handle e.g. FTP, but I'm just throwing an exception for now.
return hRes.StatusCode / 100 == 2;
}
}
catch (WebException)
{
return false;
}
}
Of course there are poor websites out there that return a 200 all the time and so on, but this is the best one can do. It assumes that in the case of a redirect you care about the ultimate target of the redirect (do you finally end up on a successful page or an error page), but if you care about the specific URI you could turn off automatic redirect following, and consider 3xx codes successful too.
There is a Ping class you can utilize for that, more details can be found here:
http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping.aspx
I did something similar when I wrote a torrent client to check valid tracker URLS, pretty sure I found the answer on SO but cant seem to find it anymore, heres the code sample I have from that post.
using(var client = new WebClient()) {
client.HeadOnly = true;
// exists
string Address1 = client.DownloadString("http://google.com");
// doesnt exist - 404 error
string Address2 = client.DownloadString("http://google.com/sdfsddsf");
}

Categories

Resources