How to catch and re-throw exceptions

There are two ways to catch and re-throw an exception, below the two code snippets:

Snippet #1:

   1:  try
   2:  {
   3:   
   4:  }
   5:  catch(Exception ex)
   6:  {
   7:    throw ex;
   8:  }

Snippet #2:

   1:  try
   2:  {
   3:   
   4:  }
   5:  catch(Exception ex)
   6:  {
   7:    throw;
   8:  }

When you use snippet #1, you will re-throw the same exception object and as result of this the original stack trace will be lost. Snippet #2 will maintain the original stack trace, this is very useful for debugging.

One of the try/catch general exception handling guidelines says:

“Do not rethrow by throwing the same exception object. This causes the stack trace for the original exception to be lost--use a lone "throw;" statement (without an object following it) to "rethrow" a catch exception.”

The best way to see the difference is with a code example:

   1:  class Program
   2:  {
   3:    static void Main(string[] args)
   4:    {
   5:      try
   6:      {
   7:        Method1();
   8:      }
   9:      catch (Exception ex)
  10:      {
  11:        throw;
  12:      }
  13:    }
  14:   
  15:    public static void Method1()
  16:    {
  17:      Method2();
  18:    }
  19:   
  20:    public static void Method2()
  21:    {
  22:      throw new Exception();
  23:    }    
  24:  }

The following stack trace will be produced by the code example above:

   at ConsoleApplication2.Program.Method2() 
   at ConsoleApplication2.Program.Method1()
   at ConsoleApplication2.Program.Main(String[] args)
   at System.AppDomain.ExecuteAssembly(Assembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

When you use throw ex; instead of throw; you will get:

   at ConsoleApplication2.Program.Main(String[] args)
   at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

As you see the stack trace don’t have the calls to Method1 and Method2, so when you use throw ex; you will lose essential debug information.

2 Comments

Comments have been disabled for this content.