Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET Catch General Exceptions

.NET Programming guidelines state that we should not catch general exceptions. I assume the following code is not very good because of the general exception type catch:

    private object CreateObject(string classname)
    {
        object obj = null;
        if (!string.IsNullOrEmpty(classname))
        {
           try
           {
              System.Type oType = System.Type.GetTypeFromProgID(customClass);
              obj = System.Activator.CreateInstance(oType);
           }
           catch (Exception ex)
           {
               Log.Error("Unable to create instance for COM Object with class name " + classname + "\n" + ex.Message);
           }
        }
        return obj;
    }

In the following code I catch particular exceptions but not all of them and then I re-throw the exception in case is different from the non-generic exceptions. However the function "CreateInstance" can throw many exceptions (ArgumentNullException, ArgumentException, NotSupportedException, TargetInvocationException, MethodAccessException, MemberAccessException, InvalidComObjectException, MissingMethodException, COMException, TypeLoadException).

Is it acceptable to catch all other individual exceptions? Or is there a better way?

    private object CreateObject(string classname)
    {
        object obj = null;
        if (!string.IsNullOrEmpty(classname))
        {
           try
           {
              System.Type oType = System.Type.GetTypeFromProgID(customClass);
              obj = System.Activator.CreateInstance(oType);
           }
           catch (NotSupportedException ex)
           {
              Log.Error("...." + ex.Message);
           }
           catch (TargetInvocationException ex)
           {
              Log.Error("...." + ex.Message);
           }
           catch (COMException ex)
           {
              Log.Error("...." + ex.Message);
           }
           catch (TypeLoadException ex)
           {
              Log.Error("...." + ex.Message);
           }
           catch (InvalidComObjectException ex)
           {
              Log.Error("...." + ex.Message);
           }
           catch (Exception ex)
           {
               Log.Error("Unable to create instance for COM Object with class name " + classname + "\n" + ex.Message);
               throw;
           }
        }
        return obj;
    }
like image 283
Ioannis Avatar asked Sep 21 '09 12:09

Ioannis


2 Answers

As a general rule you shouldn't catch exceptions unless:

  1. You have a specific exception that you can handle and do something about. However in this case you should always check whether you shouldn't be trying to account for and avoid the exception in the first place.

  2. You are at the top level of an application (for instance the UI) and do not want the default behaviour to be presented to the user. For instance you might want an error dialog with a "please send us your logs" style message.

  3. You re-throw the exception after dealing with it somehow, for instance if you roll back a DB transaction.

In this example why are you catching all these different types? It seems to me that your code can just be:

try
{
    System.Type oType = System.Type.GetTypeFromProgID(customClass);
    return System.Activator.CreateInstance(oType);
}
catch (Exception ex)
{
    Log.Error("...." + ex.Message);

    //the generic catch is always fine if you then do this:
    throw;
}

So your problem is an example of rule (3) - you want to log an exception, but then continue and throw it on up.

All the different types are there so that in certain cases that you know you can handle (i.e. case 1). For instance suppose that you know that there is an unmanaged call that works around COMException - then your code becomes:

try
{
    System.Type oType = System.Type.GetTypeFromProgID(customClass);
    return System.Activator.CreateInstance(oType);
}
catch (COMException cex)
{   //deal with special case:
    return LoadUnmanaged();
}
catch (Exception ex)
{
    Log.Error("...." + ex.Message);

    //the generic catch is always fine if you then do this:
    throw;
}
like image 145
Keith Avatar answered Oct 03 '22 02:10

Keith


It's quite acceptable to catch general exceptions in .NET 2+ of the framework.

-- Edit

The only reason you wouldn't, is if you can do something different with a different exception. If you plan on handling them all the same, just catch the general (or specific one you are after, and let anything else go up).

like image 35
Noon Silk Avatar answered Oct 03 '22 00:10

Noon Silk