What is the best way to reuse exception handling logic in C #?

I have two functions that have quite different logic, but almost the same exception handling:

public void DoIt1  // DoIt2 has different logic but same exception handling
{
    try
       ... DoIt1 logic
    catch (MySpecialException myEx)
    {
       Debug.WriteLine(myEx.MyErrorString);
       throw;
    }
    catch (Exception e)
    {
       Debug.WriteLine(e.ToString());
       throw;
    }
}

It is not possible to use the same entry point for DoIt1 and DoIt2, because they are called externally. Is Copy / Pase (for exception block) a better approach?

+5
source share
5 answers

It depends on whether there is significant generality, you can pass the item that needs to be done as a parameter, either as an interface or as a delegate:

void Foo(Action thingToDo) {
    if(thingToDo == null) throw new ArgumentNullException("thingToDo");
    try {
        thingToDo();
    } catch {...} // lots of
}

And called like:

Foo(delegate { /* logic A */ });

Foo(delegate { /* logic B */ });
+6
source

Try:

public static class Catching<TException> where TException : Exception
{
    public static bool Try<T>(Func<T> func, out T result)
    {
        try
        {
            result = func();
            return true;
        }
        catch (TException x) 
        {
            // log exception message (with call stacks 
            // and all InnerExceptions)
        }

        result = default(T);
        return false;
    }

    public static T Try<T>(Func<T> func, T defaultValue)
    {
        T result;
        if (Try(func, out result))
            return result;

        return defaultValue;
    }
}

Example:

int queueSize = Catching<MyParsingException>
    .Try(() => Parse(optionStr, "QueueSize"), 5);

Parse MyParsingException, queueSize 5, Parse ( , , ).

, .

, . - .

+5

, Aspect-Oriented-Programming , PostSharp Microsoft Policy. , , - , , .

+2

If you just want to log messages and exception items without doing any special processing in the catch block, you can create a reflection-based repository by passing the exception as an argument. However, you do not have many catch blocks.

And if you own the code, you can put the logging procedure inside the MySpecialException constructor by deleting the catch block and clearing the code.

+1
source

You might have something like:

public static class ErrorHandler
{

    public static void HandleMyException(MyException myEx)
    {
        Debug.WriteLine(myEx.MyErrorString);
        throw;
    }

    public static void HandleException(Exception myEx)
    {
        Debug.WriteLine(e.ToString());
        throw;
    }

}

or, in this particular case, have a more general function of the type:

public static class ErrorHandler
{

    public static void WriteAndThrow(string msg)
    {
        Debug.WriteLine(msg);
        throw;
    }

}
0
source

All Articles