Only Bolivian Here
Only Bolivian Here

Reputation: 36743

Exception handling the right way for WebClient.DownloadString

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:

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

Upvotes: 23

Views: 56193

Answers (4)

Ogglas
Ogglas

Reputation: 69968

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

Upvotes: 10

Avatar2012
Avatar2012

Reputation: 51

I use this code:

  1. 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"));
    }
    
  2. 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.

Upvotes: 5

Thomas Levesque
Thomas Levesque

Reputation: 292425

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...

Upvotes: 21

Jacob
Jacob

Reputation: 78840

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.

Upvotes: 1

Related Questions