Search code examples
c#exceptiontry-catchrethrow

An Exception Handling Class


What is the best practice for handling exceptions without having to put try/catch blocks everywhere?

I had the idea of creating a class that is devoted to receiving and handling exceptions, but I am wondering if its a good design idea. Such a class would receive an exception and then decide what to do with it depending on its type or error code, could even parse the stack trace for specific information, etc.

Here is the basic idea behind and implementation:

public class ExceptionHandler
{
    public static void Handle(Exception e)
    {
        if (e.GetBaseException().GetType() == typeof(ArgumentException))
        {
            Console.WriteLine("You caught an ArgumentException.");
        }
        else
        {
            Console.WriteLine("You did not catch an exception."); 
            throw e;   // re-throwing is the default behavior
        }
    }
}

public static class ExceptionThrower
{
    public static void TriggerException(bool isTrigger)
    {
        if (isTrigger)
            throw new ArgumentException("You threw an exception.");
        else
            Console.WriteLine("You did not throw an exception."); 
    }
}

class Program
{
    static void Main(string[] args)
    {
        try
        {
            ExceptionThrower.TriggerException(true); 
        }
        catch(Exception e)
        {
            ExceptionHandler.Handle(e);  
        }
        Console.ReadLine(); 
    }
}

I thought this would be an interesting endeavor because you would theoretically only need one or very few try / catch blocks around your main() method calls, and let the exception class handle everything else including re-throwing, handling, logging, whatever.

Thoughts?


Solution

  • There is actually a good reason why you don't see similar designs in production code.

    First of all, such a design cannot help you reduce the count of try/catch pairs in your code (this should be obvious). It could help you reduce the number of catch statements for a given try, since you could just catch System.Exception and forward to the ExceptionHandler...

    But what next?

    Every exception needs to be handled differently. How would the ExceptionHandler know exactly what to do? You could try to solve this in a number of ways, e.g.:

    1. Derive from ExceptionHandler and put the code to handle exceptions in virtual methods
    2. Pass a number of Action<Exception> instances to the handler and have it invoke the proper one

    Solution (1) would be worse than what you had before: now you need to create a whole new class for each try block and override a bunch of methods to end up with something worse than you had before (it's not immediately clear how the code in a particular class fits in the flow of your program). It would also leave another important question unanswered: you may need context (access to variables in the current scope) to properly handle the exception. How will you provide access to this context?

    Solution (2) would actually end up quite similar to writing the catch blocks that we 've been wanting to avoid (each Action would be effectively the contents of a catch block). We end up doing the same thing, only in a more complicated and verbose manner.

    There are also other issues:

    • What should ExceptionHandler do if it cannot handle the exception? Throwing it again will cause you to lose the original stack trace, in effect destroying all the good information in there.
    • What if there's a bug in ExceptionHandler? You can truse a try/catch. Can you trust code you wrote yourself to the same degree?

    As for the ExceptionThrower... what benefit could it possibly offer over throw new Exception();?

    Exception handling is a complicated matter already, and it's difficult enough to get it right without adding extra gears to the machine. Especially if they don't buy you anything new. Don't do it.