Exception handling the right way for WebClient.DownloadString - c#

I was wondering what exceptions I should protect myself against when using WebClient.DownloadString.
Here's how I'm currently using it, but I'm sure you guys can suggest better more robust exception handling.
For example, off the top of my head:
No internet connection.
Server returned a 404.
Server timed out.
What is the preferred way to handle these cases and throw the exception to the UI?
public IEnumerable<Game> FindUpcomingGamesByPlatform(string platform)
{
string html;
using (WebClient client = new WebClient())
{
try
{
html = client.DownloadString(GetPlatformUrl(platform));
}
catch (WebException e)
{
//How do I capture this from the UI to show the error in a message box?
throw e;
}
}
string relevantHtml = "<tr>" + GetHtmlFromThisYear(html);
string[] separator = new string[] { "<tr>" };
string[] individualGamesHtml = relevantHtml.Split(separator, StringSplitOptions.None);
return ParseGames(individualGamesHtml);
}

If you catch WebException, it should handle most cases. WebClient and HttpWebRequest throw a WebException for all HTTP protocol errors (4xx and 5xx), and also for network level errors (disconnection, host not reachable, etc)
How do I capture this from the UI to show the error in a message box?
I'm not sure I understand your question... Can't you just show the exception message?
MessageBox.Show(e.Message);
Don't catch the exception in FindUpcomingGamesByPlatform, let it bubble up to the calling method, catch it there and show the message...

I usually handle it like this to print any exception message the remote server is returning. Given that the users are allowed to see that value.
try
{
getResult = client.DownloadString(address);
}
catch (WebException ex)
{
String responseFromServer = ex.Message.ToString() + " ";
if (ex.Response != null)
{
using (WebResponse response = ex.Response)
{
Stream dataRs = response.GetResponseStream();
using (StreamReader reader = new StreamReader(dataRs))
{
responseFromServer += reader.ReadToEnd();
}
}
}
_log.Error("Server Response: " + responseFromServer);
MessageBox.Show(responseFromServer);
}

I use this code:
Here I init the webclient whithin the loaded event
private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
{
// download from web async
var client = new WebClient();
client.DownloadStringCompleted += client_DownloadStringCompleted;
client.DownloadStringAsync(new Uri("http://whateveraurisingis.com"));
}
The callback
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
#region handle download error
string download = null;
try
{
download = e.Result;
}
catch (Exception ex)
{
MessageBox.Show(AppMessages.CONNECTION_ERROR_TEXT, AppMessages.CONNECTION_ERROR, MessageBoxButton.OK);
}
// check if download was successful
if (download == null)
{
return;
}
#endregion
// in my example I parse a xml-documend downloaded above
// parse downloaded xml-document
var dataDoc = XDocument.Load(new StringReader(download));
//... your code
}
Thanks.

According to the MSDN documentation, the only non-programmer exception is WebException, which can be raised if:
The URI formed by combining BaseAddress and address is invalid.
-or-
An error occurred while downloading the resource.

Related

400 Bad request on c# code

Getting an error exception thrown on this small piece of code but I can't figure out why / where. Fairly new to this so any help would be apprecaited
private void GetServiceData(string url)
{
try
{
if (!string.IsNullOrEmpty(this.Service) && !string.IsNullOrEmpty(url))
{
string data = string.Empty;
string name = string.Format("{0}Data", this.Service);
using (WebClient client = new WebClient())
{
data = client.DownloadString(url);
}
Page.ClientScript.RegisterHiddenField(name, data);
}
}
catch (Exception ex)
{
Shared.Utilities.ExceptionLog.WriteExceptionToLog(ex, "CourseFinderServiceControl.GetServiceData()");
}
}
If this is for Twitch, you need to specify client when requesting the data.

Download vimeo video through its URL

I am trying to achieve this for vimeo videos through C# code, but the file being downloaded is the HTML. Can someone tell me how to do this? Below you can find the two handlers I implemented. Both have the same behaviour that I already described.
Handle.GET("/testDownload", (Request r) =>
{
Response response = 0;
try
{
WebClient webClient = new WebClient();
webClient.DownloadFile("https://player.vimeo.com/video/140308351", #"c:\binte\test");
}
catch (Exception ex)
{
GlobalDictionary.errorLog.LogError("Error in test download handler : " + ex.Message);
}
response.Body = "success";
return response;
}, new HandlerOptions() { SkipMiddlewareFilters = true });
Handle.GET("testDownloadVideo?url={?}", (string url, Request r) =>
{
Response response = 0;
string fileName = "testDownload.mpeg";
try
{
using (WebClient myWebClient = new WebClient())
{
myWebClient.DownloadFileAsync(new Uri(url), fileName);
}
}
catch (Exception ex)
{
GlobalDictionary.errorLog.LogError("Error in test download handler : " + ex.Message);
}
response.Body = "success";
return response;
}, new HandlerOptions() { SkipMiddlewareFilters = true });
EDIT: After some research, I think this is not possible to be done, unless I would be the owner of the video, and therefore able to use the API for that purpose. I will leave the question open though, one day this might change.

How to catch exception?

I am trying to call api and check its response, but when ever some wrong value is passed it stops the program. I want to add exception during request and response but not sure how to write in function.
This is how i call my REST call
public dynamic APICalls(JObject ljson, string endpoints, string method)
{
var httpReq = (HttpWebRequest)HttprequestObject(endpoints, method);
using (var streamWriter = new StreamWriter(httpReq.GetRequestStream()))
{
streamWriter.Write(ljson);
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse)httpReq.GetResponse();
var result = "";
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
result = streamReader.ReadToEnd();
}
return result;
//return "Success";
//not sure what to return
//here i have to add sql server code to enter into database
}
THis is code for request
public dynamic HttprequestObject(string endpoints, string method)
{
string url = Settings.API_TEST_VALUE + endpoints;
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = method;
return httpWebRequest;
}
And right before request and right after response i want to catch exception.
At this point i have to catch exception
var httpResponse = (HttpWebResponse)httpReq.GetResponse();
If some one gives me hint how to catch that before it stops program.
There are 400, 401,402 errors, if something is wrong API sends json
For instance, while creating user :-- Email id already exists
But that points stops json and stops program..
Using try catch it will stop program, I want it to run and want to receive resposne.
Actually, API will send error .
For instance, status will be ;---401 UNAUTHORIZED
and resposnse will be
{ "reason": "Email already registered.", "success": false }
I am changed my code and
HttpWebResponse httpResponse;
try
{
//HttpWebResponse myHttpWebResponse = (HttpWebResponse)httpReq.GetResponse();
httpResponse = (HttpWebResponse)httpReq.GetResponse();
//myHttpWebResponse.Close();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
result = streamReader.ReadToEnd();
}
}
catch (WebException e)
{
Console.WriteLine("This program is expected to throw WebException on successful run." +
"\n\nException Message :" + e.Message);
if (e.Status == WebExceptionStatus.ProtocolError)
{
Console.WriteLine("Status Code : {0}", ((HttpWebResponse)e.Response).StatusCode);
Console.WriteLine("Status Description : {0}", ((HttpWebResponse)e.Response).StatusDescription);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return result;
//return "Success";
//not sure what to return
//here i have to add sql server code to enter into database
}
This is the new code, but I m not getting Json as return value, So i can show specific error.
For below Json what should I write?
{ "reason": "Email already registered.", "success": false }
please I m new to c# and if something is not clear please modify or ask question?
thank you
What you're looking for is called a try-catch statement:
try
{
var httpResponse = (HttpWebResponse)httpReq.GetResponse();
}
catch (WebException e)
{
// Here is where you handle the exception.
}
Using WebException as the type in the catch statement means only exceptions of that particular type will be caught.
In case an exception occurs, the e variable will contain exception details, such as a message passed from the method which three the exception and any inner exceptions encapsulated inside.
You can handle your web exceptions to get HttpStatusCode and Response Message this way:
public void SendAndGetResponseString()
{
try
{
// Here you call your API
}
catch (WebException e)
{
var result = GetResponceFromWebException(e);
if (result != null){
//
// Here you could use the HttpStatusCode and HttpResponseMessage
//
}
throw;
}
catch (Exception e)
{
// log exception or do nothing or throw it
}
}
private HttpRequestResponce GetResponceFromWebException(WebException e)
{
HttpRequestResponce result = null;
if (e.Status == WebExceptionStatus.ProtocolError)
{
try
{
using (var stream = e.Response.GetResponseStream())
{
if (stream != null)
{
using (var reader = new StreamReader(stream))
{
var responseString = reader.ReadToEnd();
var responce = ((HttpWebResponse) e.Response);
result = new HttpRequestResponce(responseString, responce.StatusCode);
}
}
}
}
catch (Exception ex)
{
// log exception or do nothing or throw it
}
}
return result;
}
public class HttpRequestResponce {
public HttpStatusCode HttpStatusCode { get;set; }
public string HttpResponseMessage {get;set;}
public HttpRequestResponce() { }
public HttpRequestResponce(string message, HttpStatusCode code)
{
HttpStatusCode=code;
HttpResponseMessage=message;
}
}
You encapsulate whatever method call or code block you want to prevent from throwing unhandled exceptions.
try
{
// code here
}
catch (Exception)
{
// here you may do whatever you want to do when an exception is caught
}
Ok,Finally I am able to Solve this.. Thanks everyone for you help.
This worked for me. I think I was not reading whole response.. So some how I think I realized and now its working ..
HttpWebResponse httpResponse;
try
{
httpResponse = (HttpWebResponse)httpReq.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
result = streamReader.ReadToEnd();
}
}
catch (WebException e)
{
Console.WriteLine("This program is expected to throw WebException on successful run." +
"\n\nException Message :" + e.Message);
if (e.Status == WebExceptionStatus.ProtocolError)
{
Console.WriteLine("Status Code : {0}", ((HttpWebResponse)e.Response).StatusCode);
Console.WriteLine("Status Description : {0}", ((HttpWebResponse)e.Response).StatusDescription);
using (Stream data = e.Response.GetResponseStream())
using (var reader = new StreamReader(data))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}

C# Exceptions Not Being Handled

The following code is called via the browser and if an exception occurs that exception is never caught by the 'Try Catch' but instead the exception is reported to the screen. I have tried running without debug as well as turning off CLR errors. Any suggestions would be appreciated:
public string GetUrl(string url)
/*Grab remote page */
{
string target = string.Empty;
HttpWebRequest httpWebRequest = null;
HttpWebResponse response = null;
StreamReader streamReader = null;
try
{
httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
response = (HttpWebResponse)httpWebRequest.GetResponse();
streamReader = new StreamReader(response.GetResponseStream(), true);
target = streamReader.ReadToEnd();
}
catch (WebException e)
{
Console.WriteLine("Error:GetUrl()");
Console.WriteLine("\n{0}", e.Message);
Console.WriteLine("\n{0}", e.Status);
}
finally
{
streamReader.Close();
response.Close();
}
return target;
}
You are only catching webexceptions, any other exception is not caught.
It can throw more exceptions see here :
https://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.getresponse%28v=vs.110%29.aspx
Add one more catch block before finally block and trap base Excaption. It will catch all type of error occurred and not caught in earlier catch blocks.

request.timeout doesn't throw exception

Uri URL2 = new Uri(#"http://www......com");
HttpWebRequest request2 = (HttpWebRequest)WebRequest.Create(URL2);
request2.Timeout = 10000;
HttpWebResponse response2 = (HttpWebResponse)request2.GetResponse();
I am making webrequest with the codes above. When I write a stupid url such as www.oiasjdilasod.com it throws exception; however when an existing page is not available for few hours I cannot get this exception. it doesn't throw any exception and stop running.
When this page is not available i tried at internet explorer, it showed page can not be found http 400 bad request.
Do you have any suggestions how to catch this exception?
The fact that you are getting a response back from the server means that it's available, it's just not working properly - therefore the request is made and doesn't time out because the server has responded.
It's just not the response you wanted.
Instead, you should check the StatusCode property.
if(response2.StatusCode != HttpStatusCode.OK)
{
throw new Exception("Site is responding incorrectly!");
}
i had the same problem before and
catch(WebException e)
{
Console.WriteLine(e.toString());
}
will solve it
This Piece of Code Worked for me
try
{
Uri URL2 = new Uri(#"http://www.*****.com");
HttpWebRequest request2 = (HttpWebRequest)WebRequest.Create(URL2);
request2.Timeout = 100;
HttpWebResponse response2 = (HttpWebResponse)request2.GetResponse();
}
catch (WebException e)
{
MessageBox.Show(e.Message.ToString());
}
What exception are you throwing? A regular Exception won't do, it has to be a WebException.
...
catch(WebException e)
{
Console.WriteLine("Error: "+ e.Status);
}
EDIT:
How about a Timeout Exception (Along with the WebException)?
catch (TimeoutException e)
{
Console.WriteLine(e);
}
catch(WebException e)
{
Console.WriteLine("Error: "+ e.Status);
}

Categories

Resources