I am having an issue with my variable httpRes. Basically this is the basics of a command line app that will check a set of given URL's and return their status code, i.e. unauthorized, redirect, ok etc. The problem is one of the apps within my list keeps throwing an error. So I used a try catch clause to catch the error and tell me what caused it.
Unfortunately the variable httpRes works in the try clause, but not in the catch. It keeps being returned as null. I called httpRes outside of the try/catch statement so I am hoping my scope is correct but for whatever reason the value never changes from null for the catch statement, only the try statement.
Here is the code referenced.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace URLMonitor
{
class Program
{
static void Main(string[] args)
{
string url1 = "https://google.com"; //removed internal URL for security reasons.
HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(url1);
httpReq.AllowAutoRedirect = false;
HttpWebResponse httpRes = null;
try
{
httpRes = (HttpWebResponse)httpReq.GetResponse();
if (httpRes.StatusCode == HttpStatusCode.OK)
{
Console.WriteLine("Website is OK");
// Close the response.
//httpRes.Close();
}
}
catch
{
if (httpRes != null)
{
if (httpRes.StatusCode == HttpStatusCode.Unauthorized)
{
Console.WriteLine("Things are not OK");
//httpRes.Close();
}
}
else
{
Console.WriteLine("Please check the URL and try again..");
//httpRes.Close();
}
}
Console.ReadLine();
}
}
}
Well if you catch an exception, that would probably be because GetResponse failed, right? So you wouldn't have assigned anything to httpRes yet...
It seems to me that you should be catching WebException, at which point you can look at the response - if there is one:
catch (WebException e)
{
// We're assuming that if there *is* a response, it's an HttpWebResponse
httpRes = (HttpWebResponse) e.Response;
if (httpRes != null)
{
...
}
}
It's pretty much never worth writing a bare catch block, btw - always at least catch Exception, but ideally catch a more specific exception type anyway, unless you're at the top level of your application stack.
Personally I wouldn't bother using the same variable for both pieces of code - I'd declare the response for the success case within the try block, and the response for the failure case in the catch block. Also note that you should normally be disposing of your WebResponse, e.g.
using (var response = request.GetResponse())
{
// Use the response
}
I don't believe you need to do this if GetResponse throws an exception and you obtain the response from the exception.
Related
My app produces the following error randomly. I havent been able to re-produce it on my machine, but on users who have installed it, it happens to them.
System.Net.WebException: The request was aborted: The request was canceled.
at System.Net.ConnectStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.IO.StreamReader.ReadBuffer()
at System.IO.StreamReader.ReadToEnd()
Whats odd is, ReadToEnd() cant product a WebException error (Found out by hovering over it and seeing what type of exceptions it can cause), yet from this Crash Dump it is?, To make sure I even put a WebException try catch and it still happens.
I read online a tiny bit and see it might be caused by ServicePointManager.DefaultConnectionLimit so I added that in with 1000 int value, and now im not sure if it fixed it - I havent seen any reports, but that doesnt mean its not happening.
using (HttpWebResponse resp = (HttpWebResponse)r.GetResponse())
using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
{
string s = "";
try { s = sr.ReadToEnd(); }
catch (IOException) { return "2"; }
catch (WebException) { return "2"; }
}
This is the code im using, if needed, I can provide r's values. Just know that I use quite a lot.
EDIT: I can confirm on the client's side that even with the ServicePointManager.DefaultConnectionLimit set to 1000 it still occurs.
I had a similar problem to this some time ago. Can you handle the WexException doing something like this:
public static HttpWebResponse GetHttpResponse(this HttpWebRequest request)
{
try
{
return (HttpWebResponse) request.GetResponse();
}
catch (WebException ex)
{
if(ex.Response == null || ex.Status != WebExceptionStatus.ProtocolError)
throw;
return (HttpWebResponse)ex.Response;
}
}
I borrowed the code above from the answerer here: HttpWebRequest.GetResponse throws WebException on HTTP 304
Then the first line of your code would do this:
using (HttpWebResponse resp = GetHttpResponse(r))
Found out what managed to fix it, no idea WHY, but this works:
try
{
using (HttpWebResponse resp = httpparse.response(r))
{
if(resp != null)
{
using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
{
string s = "";
try { s = sr.ReadToEnd(); }
catch (IOException) { return "2"; }
}
} else
{
return "2";
}
}
}
catch (WebException)
{
return "2";
}
Makes no sense, the error occurs at sr.ReadToEnd(), yet putting the Try Catch over the response() makes it fixed?
I'm using this code, to fetch the latest version of my app in *Form1_Load*:
string result1 = null;
string url1 = "http://site.com/version.html";
WebResponse response1 = null;
StreamReader reader1 = null;
try
{
HttpWebRequest request1 = (HttpWebRequest)WebRequest.Create(url1);
request1.Method = "GET";
response1 = request1.GetResponse();
reader1 = new StreamReader(response1.GetResponseStream(), Encoding.UTF8);
result1 = reader1.ReadToEnd();
}
catch (Exception ex)
{
// show the error if any.
}
finally
{
if (reader1 != null)
reader1.Close();
if (response1 != null)
response1.Close();
}
The problem is that when I shut the server down the whole application is stucking and a window is popping out,saying:
Unable to connect to the remote server
Which seems legit.
Is there a way to bypass this crash (when the server is down) and break out of the version checking?
Add an additional catch block that catches the specific Exception type that you're seeing... the code will look like...
try
{
//*yadda yadda yadda*
}
catch (System.Net.WebException WebEx)
{
//*Correctly set up a situation where the rest of your program will know there was a connection problem to the website.*
}
catch (Exception ex)
{
//*Do the error catching you do now*
}
finally
{
//*yadda yadda*
}
This construction will allow you to handle WebExceptions differently from other kinds of exceptions: note that all Exceptions derive from one base class, Exception, and you can make your own for uses like this.
I am trying to catch any errors that crop up when a URL is invalid, below is the original code:
public static void mymethod()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(firstline);
Stopwatch timer = new Stopwatch();
timer.Start();
using (var response = request.GetResponse())
timer.Stop();
timeTaken = timer.Elapsed.ToString();
}
I have tried to create an exception handler as below, but no luck:
public static void mymethod()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(firstline);
Stopwatch timer = new Stopwatch();
timer.Start();
try
{
using (var response = request.GetResponse())
}
catch
{
Console.WriteLine("error here...")
}
timer.Stop();
timeTaken = timer.Elapsed.ToString();
}
You should do something like this.
public static void ShowResponseAndTimeTaken(string firstline)
{
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(firstline);
System.Diagnostics.Stopwatch timer = new Stopwatch();
timer.Start();
using (var response = request.GetResponse())
{
Console.WriteLine("Response : {0}", response);
}
timer.Stop();
Console.WriteLine("Time taken : {0}", timer.Elapsed);
}
catch(Exception e)
{
Console.WriteLine("error : {0}", e.Message);
}
}
Your usage of using-block is incorrect. The correct looks like this:
using (var response = request.GetResponse())
{
}
or just without the block:
var response = request.GetResponse();
response.Dispose()
I believe you cannot intercept it because it is thrown before "try" block:
it is possible that "firstline" variable contains a text with perhaps incorrectly formatted uri,
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(firstline);
You can also validate URL using regex instead of waiting for exception to be thrown - http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.aspx.
Here (http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.getresponse.aspx) you can find detailed description about GetResponse. Check what exceptions can be thrown and modify your current exception handling.
You shouldn't leave try...catch as it is. At least catch Exception class.
WebRequest.Create only throws if the scheme is invalid (the bit before the colon), there is a security error or if the URI you pass is null (although you have not enclosed that statement inside your try statement so such errors will be unhandled by the above code anyway).
To handle other errors, you should look at the HttpWebResponse.StatusCode property and handle the HTTP errors in way appropriate to your application.
I think you are talking about syntactic errors, because your code does not compile?
Try to add the missing semicolon on this line:
Console.WriteLine("error here...")
And the using-block contains no block:
using (var response = request.GetResponse())
remove the using:
var response = request.GetResponse())
I created a simple console application using C#. It creates an instance of a class and calls one of the class' methods. This method contains a try-catch block to catch exceptions of the type System.Net.WebException and rethrow it so that the main method can catch it and act appropriately. When I execute the compiled application the exception does not get passed to the main class and the user would never see my custom error message. Instead this screen pops up telling me that there was an unhandled WebException (it's in German but I think it can be recognized anyway ;-)):
alt text http://img29.imageshack.us/img29/4581/crapq.png
This is the method inside my class named BuffaloRouter:
public void Login()
{
string sUrl = _sUrl + "/somestuff.htm";
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(sUrl);
CredentialCache credCache = new CredentialCache();
credCache.Add(new Uri(sUrl), "Basic", _credential);
request.Credentials = credCache;
try
{
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream receiveStream = response.GetResponseStream();
StreamReader reader = new StreamReader(receiveStream, Encoding.UTF8);
_sContent = reader.ReadToEnd();
response.Close();
receiveStream.Dispose();
reader.Dispose();
_parseSessionIds();
}
catch (WebException)
{
throw;
}
}
And this is the method inside my main class:
private static bool _login()
{
_router = new BuffaloRouter(_sIP, new System.Net.NetworkCredential("root", _sPassword));
try
{
Console.WriteLine("Login...");
_router.Login();
return true;
}
catch (System.Net.WebException)
{
_showErrorMessage("Could not connect to " + _sIP);
return false;
}
}
UPDATE:
I feel more than a little embarrassed and would rather not talk about it. But like a few times before I didn't relly look at what I was doing ;-)
The method inside the main class was not even invoked when I was running the app. The one that was invoked didn't have a try-catch block so that the exception thrown inside my class' method made the app do what it was supposed to, i.e. CRASH!!
I'm stupid, sorry for wasting everone's time.
If all you're doing is rethrowing the exception, then you don't need to catch it in the first place. Just remove the try...catch from your Login method.
Having done that temporarily edit your code to catch the general exception and debug it to find out what exception is actually being raised. Having done that edit the code again to catch that exception (and that exception alone).
As ChrisF has indicated you don't need to rethrow the error in the Login method. If your catch block is not running in the _login method, then I would guess your not catching the right exception.
Are you positive your getting a System.Net.WebException
I have some C# code that pulls down a remote website using the HttpWebRequest class. I'm handling errors with a try/catch, but some errors (like Webrequest and IOException) don't seem to be getting "caught" with the way I have it setup:
try
{
StartScrap("http://www.domain.com");
}
catch (Exception ex)
{
LogError(ex.ToString();
}
private void StartScrap(string url)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
Stream responseStream = response.GetResponseStream();
string responseText = String.Empty;
using (StreamReader readerStream = new StreamReader(responseStream, System.Text.Encoding.UTF8))
{
responseText = readerStream.ReadToEnd(); <-- I will sometimes get a Webexception error here that won't get caught above and stops the code
}
}
}
Update: There is more to the code, so maybe it is something outside of the code I posted? I am basically using this code in a Windows Application on a form that has a NotifyIcon. I'm using the Timer class to run the code at a certain timer interval. This is how I have it setup:
public TrayIcon()
{
InitializeComponent();
}
private void TrayIcon_Load(object sender, EventArgs e)
{
try
{
StartScrap("http://www.domain.com");
}
catch (Exception ex)
{
LogError(ex.ToString());
}
finally
{
StartTimer();
}
}
private void StartTimer()
{
Timer Clock = new Timer();
Clock.Interval = 600000;
Clock.Start();
Clock.Tick += new EventHandler(TrayIcon_Load);
}
What exactly do you mean by "stops the code"? Are you running in a debugger by any chance? My guess is that if you run outside the debugger - or just hit "run" again in the debugger - you'll get into the catch block with no problems. Alternatively, go into the debugger settings and change at which point the debugger steps in.
Of course, if this isn't happening in the debugger, we just need more information about exactly what you're seeing.
Could it be that LogError is throwing an exception?
Frankly speaking I am not sure what exactly happening but I will suggest you to go with ELMAH.(Error Logging Modules and Handlers)
Here is a step by step How to for ELMAH.
Nevermind, I found out I was calling the wrong function my Timer class and it was bypassing the event handler.