Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DRY With Different Try Statements and Identical Catch Statements

So I have the following block of code inside a method: (all variables are local)

// ...

try
{
    if (postXml != null)
        using (StreamWriter writer = new StreamWriter(req.GetRequestStream()))
            writer.Write(postXml.ToString());
}
catch (WebException ex)
{
    HttpWebResponse response = ex.Response as HttpWebResponse;
    if (response != null)
        result = HandleOtherResponse(response, out status);
    else result = HandleBadResponse(ex.ToString(), out status);
}
catch (Exception ex)
{
    result = HandleBadResponse(ex.ToString(), out status);
}

if (result == null)
{
    try
    {
        HttpWebResponse response = req.GetResponse() as HttpWebResponse;
        result = HandleOtherResponse(response, out status);
    }
    catch (WebException ex)
    {
        HttpWebResponse response = ex.Response as HttpWebResponse;
        if (response != null)
            result = HandleOtherResponse(response, out status);
        else result = HandleBadResponse(ex.ToString(), out status);
    }
    catch (Exception ex)
    {
        result = HandleBadResponse(ex.ToString(), out status);
    }
}

// ...

As you can see, the two try statements are different, but the two sets of catch statements are exactly the same. I've been trying to think of a way that it might be possible to not repeat myself here, but I haven't really thought of a way that wouldn't be significantly slower or just as terrible looking. Wondering if anyone has any ideas.

like image 930
Maltor Avatar asked Jun 26 '13 21:06

Maltor


1 Answers

One way would be to write a "safe" invocation method and pass a func to it:

public T SafeInvocation(Func<T> myMethod)
{
    T result = default(T);

    try
    {
        // Invoke method
        result = myMethod();
    }
    catch
    {
        // Do your common catch here
    }

    return result;
}

Build an additional overload for Action<T> so that you don't need to have a return type. Then you could invoke it elsewhere, passing methods to your method as arguments (Inception?):

SafeInvocation(() => 
{
    if (postXml != null)
        using (StreamWriter writer = new StreamWriter(req.GetRequestStream()))
            writer.Write(postXml.ToString());
}
like image 91
Haney Avatar answered Sep 23 '22 21:09

Haney