1

A developer has written the following code below and I am trying to find a better way to refactor it:

            try
            {
                using (var client = new WebClient())
                {
                    var proxy = new WebProxy(address, portNo);
                    proxy.BypassProxyOnLocal = false;
                    proxy.UseDefaultCredentials = true;
                    client.UseDefaultCredentials = true;

                    result = client.DownloadString(httpURL);
                }
            }
            catch (Exception ex)
            {
                log.Error("blah blah", ex);

                try
                {
                   SendNotification
                }
                catch (Exception emailEx)
                {
                    log.Error("blahblah " + emailEx);
                }
            }

Is the using clause required to be inside a try/catch block, considering it itself is using try/finally? And then if an exception is thrown inside the using, how do I handle it?

Is there a better way to avoid the nested try/catch when sending a notification?

6
  • 5
    Move the SendNotification code to its own method. Commented Mar 13, 2020 at 9:10
  • 1
    1) Create a method called public void SendNotificationCatchExceptions(), 2) Move your nested try/catch into that method. 3) Call SendNotificationCatchExceptions() from your main catch block. Commented Mar 13, 2020 at 9:13
  • you mean call the sendnotification from the parent exception method and then do the try catch within the SendNotification method itself? is that much different from above except it is bit more maintainable? Commented Mar 13, 2020 at 9:13
  • It isn't, but I don't see another way that this can go down. You only want to send the notification when an error is caught, and you don't want to error out if the send notification code fails. So the logical conclusion is that the nested try/catch has to exist, whether it's in the code above, or in another method. I'm working under the assumption that SendNotification will require the outermost exception, of course. Commented Mar 13, 2020 at 9:15
  • 1
    And : "We don't recommend that you use the WebClient class for new development. Instead, use the System.Net.Http.HttpClient class." - MS Docs , so you may also consider switching to newer tech. With HttpClient, though, you wouldn't be using using anyway (nor close it manually everytime). Commented Mar 13, 2020 at 9:23

3 Answers 3

2

Try to call SendNotification when exception is thrown and handle exceptions in SendNotification():

try 
{
    using(var client = new WebClient())
    {
        var proxy = new WebProxy(address, portNo);
        proxy.BypassProxyOnLocal = false;
        proxy.UseDefaultCredentials = true;
        client.UseDefaultCredentials = true;    
        result = client.DownloadString(httpURL);
    }
}
catch (Exception ex)
{
    log.Error("blah blah", ex); 
    SendNotification(); 
}      

And SendNotification():

private void SendNotification()
{
    try 
    {
        // Here you are sending notifications
    }
    catch (Exception emailEx)
    {
        log.Error("blahblah " + emailEx);
    }    
}
Sign up to request clarification or add additional context in comments.

Comments

1

The best way to avoid nesting is to make it in another function

catch (Exception ex)
        {
            log.Error("blah blah", ex);
            FUNCTION_NAME()
        }

private RETURN_TYPE  FUNCTION_NAME()
{
         try
        {
           SendNotification
        }
        catch (Exception emailEx)
        {
            log.Error("blahblah " + emailEx);
        }
 }

Comments

0

Many C# native libraries use the Try pattern to specify they will not throw:

For example: bool Dictionary.TryAdd(element)

public DoEverything()
{
    if(!TryDownload(..))
    {
        TrySendNotification();
    }
}

public bool TryDownload(out result)
{
    try {
        using(var client = new WebClient())
        {
            var proxy = new WebProxy(address, portNo);
            proxy.BypassProxyOnLocal = false;
            proxy.UseDefaultCredentials = true;
            client.UseDefaultCredentials = true;

            result = client.DownloadString(httpURL);
            return true;
        }
    }
    catch (Exception ex)
    {
        log.Error("blah blah", ex);  
        return false;
    }
}

public bool TrySendNotification()
{
    try 
    {
        // Here you are sending notifications
        return true;
    }
    catch (Exception emailEx)
    {
        log.Error("blahblah " + emailEx);
        return false;
    }    
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.