HttpWebResponse.StatusCode isn't trapping 500 Errors - c#

My Question:
Does a HttpWebResponse.StatusCode detect Asp.Net errors? Mainly a yellow screen of death?
Some Background:
I am working on a simple c# console app that will test servers and services to make sure they are still functioning properly. I assumed since the HttpStatusCodes are enumerated with OK, Moved, InteralServerError, etc... that I could simply do the following.
WebRequest request = WebRequest.Create(url);
request.Timeout = 10000;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response == null || response.StatusCode != HttpStatusCode.OK)
{
// SERVER IS OK
return false;
}
else
{
// SERVER HAS SOME PROBLEMS
return true;
}
I found out this morning however that this doesn't work. An ASP.Net application crashed showing a Yellow Screen Of Death and my application didn't seem to mind because the response.StatusCode equaled HttpStatusCode.OK.
What am I missing?
Thanks
// lance
Update
Thanks to Jon this seems to be working.
HttpWebResponse response;
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (WebException webexp)
{
response = (HttpWebResponse)webexp.Response;
}

GetResponse will throw a WebException for errors - but you can catch the WebException, use WebException.Response to get the response, and then get the status code from that.
As far as I'm aware, GetResponse never returns null, so you can remove that test from your code.
Also, rather than having if/else blocks to return true/false, it's simple just to return the result of evaluating an expression, for example:
return response.StatusCode == HttpStatusCode.OK;
(To be honest, you could probably return false if any WebException is thrown...)

Related

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";
}

HttpWebRequest doesn't throw exception

I have a problem with httpwebrequest exception. I use the following code to make a request and catch the exception.
try
{
Uri url= new Uri("https://www.example.com");
HttpWebRequest request2 =(HttpWebRequest)WebRequest.Create(url);
request2.Timeout = 10000;
HttpWebResponse response2 = (HttpWebResponse)request2.GetResponse();
response2.Close();
}
catch (TimeoutException)
{
listBox.Items.Insert(0, "Timeout");
}
catch (WebException ex)
{
using (WebResponse response = ex.Response)
{
HttpWebResponse httpResponse = (HttpWebResponse)response;
listBox.Items.Insert(0, "Status code(Benchmark):" + httpResponse.StatusCode);
}
}
catch
{
listBox.Items.Insert(0, "Failure");
}
At company network when I enter a non-existing url such as www.oiuahsdupiasduiuhid.com; it throws webexception . I got status code: not found or service unavailable. However If I try it at home, it doesn't throw any exception. It waits around 1 second and then without any error stops working. I delete all exceptions to see what is happening but the problem is it doesn’t show any error.
Do you have any idea about what is the problem?
Or any recommendation, how can I handle this problem with a different way?
Without knowing more about your application design, specifically exception handling further up the call stack, it is hard to say why it is behaving like it is when you are at home.
But when I just tried your exact code, it did throw a WebException, however httpResponse.StatusCode throws a NullReferenceException because httpResponse is null. If you are potentially swallowing this exception further up the call stack, it could explain the situation you are seeing.
httpResponse is going to be null in many WebException cases because your request did not receive any response, specifically in the timeout scenario.
Before casting WebException.Response, you need to check the WebException.Status property. If that status suggests a response was received, then you can go check WebException.Response, otherwise it is just going to be null. Try something like:
if(e.Status == WebExceptionStatus.ProtocolError) {
listBox.Items.Insert("Status Code : {0}",
((HttpWebResponse)e.Response).StatusCode);
}
else
{
listBox.Items.Insert("Status : {0}", ex.Status);
}
As a side note, your response2.Close(); is never going to be called when HttpWebResponse response2 = (HttpWebResponse)request2.GetResponse(); throws an exception, so you should be wrapping it in a using block:
using(HttpWebResponse response2 = (HttpWebResponse)request2.GetResponse())
{
// do something with response
}
Thanks to psubsee2003. I got my answer. here is my code which is working properly. I added following codes to webexception.
if (ex.Status == WebExceptionStatus.ProtocolError)
{
using (WebResponse response = ex.Response)
{
HttpWebResponse httpResponse = (HttpWebResponse)response;
listBox2.Items.Insert(0, "Status:" + httpResponse.StatusCode);
}
}
else
{
listBox2.Items.Insert(0, "Status: " + ex.Status);
}

How to distinguish NotFound returned from server and NotFound because of bad connectivity?

On Windows Phone, I can get WebException with StatusCode == HttpStatusCode.NotFound if
Server returned 404
Server cannot be found because of bad connectivity.
On Windows Phone WebException's status is WebExceptionStatus.UnknownError for both cases.
How can I tell case 1 from case 2?
What I observe is when connectivity is bad (server not found) ResponseUri is null and WebResponse's Headers contains 0 items.
EDIT
ResponseUri is not null, but rather has its OriginalString empty
Is it safe to do this:
catch (WebException ex)
{
switch (ex.Response.StatusCode)
{
...
case HttpStatusCode.NotFound:
if (ex.Response.ResponseUri == null
|| string.IsNullOrEmpty(httpWebResponse.ResponseUri.OriginalString))
DoServerNotFound();
else
DoServerReturned404();
Why don't use NetworkInterface.GetIsNetworkAvailable() to see if there is an active network connection before you make the web call. Otherwise, you end up waiting for nothing and waste a call. If there is a connection and the call still fails, you know that it is an issue with the web service.
I use that in my apps, if there is no connectivity, I don't bother making a call.
Thanks
Max
If you got 'Not found' exception coz of bed request this will helps.
catch (WebException ex)
{
using (WebResponse webResponse = ex.Response)
{
HttpWebResponse httpResponse = (HttpWebResponse)webResponse;
using (Stream data = webResponse.GetResponseStream())
using (var reader = new StreamReader(data))
{
string string = reader.ReadToEnd();
}
}
}

System.Net.WebException

is seems to me that WebRequest.Create(url) fails a litle to soon..
Explanations:
on a url that it failed (or throwed a System.Net.WebException) ... copy-paste -ing that url into the browser seems to work..browser gives response!.. sometimes with a remarcable delay (~10 seconds).. but WebRequest in less than 3 seconds throws exception
Example of valid url on which it fails:
http://tracker.podtropolis.com:2710/announce?info_hash=%92%FD%2F%0B%40%F64%C5%86%19%D6%3E%B1%28%B2%81%A1J%D4%F6&peer_id=-AZ2060-%AD%18%05o%11%A6%26%B3%C3%D16%AC&port=6881&downloaded=0&uploaded=0&left=647749313&numwant=30&compact=1&event=started
if it has any meaning firefox reacts 10 times more slowly on this url that explorer, also sometimes firefox crashes on loading such a url
So question Why is WebRequest failing so soon?? I would like it to try a litle harder to get response from URL...
And this is the method that catches exeption (here i check if url is valid OR ~ "is tracker alive??")
public static bool isURLValid(string url)
{
try
{
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "HEAD";
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
//Returns TURE if the Status code == 200
return (response.StatusCode == HttpStatusCode.OK);
}
catch (Exception ex) //(WebException ex)
{
Logger.e(TAG, "isURLValid", ex);
return false; //Any exception will returns false.
}
}
if valid i get stream (i know .. I know ..double contact.. but still)
inputStream = WebRequest.Create(fullURL).GetResponse().GetResponseStream();
So.. thoughts?

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