“throw;” vs “throw ex;”

Sometimes exception gets caught to make some logging and rethrow it upper (i.e. log exception in library and then throw it to client code).

In this case it’s important to understand that “throw ex;” will cut stack trace. So when caught in calling code exception will contain StackTrace and TargetSite starting from the method that rethrown it. Sometimes it’s desirable to hide real stack trace, sometimes – not.

Lets take a look at following code:

class Program
{
       static void Main(string[] args)
       {
              Program p = new Program();
              p.ClientMethod();

              Console.ReadLine();
       }

       void ClientMethod()
       {
              try
              {
                     LibraryAPI();
              }
               catch (Exception ex)
              {
                      Console.WriteLine(ex.StackTrace);
              }
       }

       void LibraryAPI()
       {
              try
              {
                     LibraryInternal();
              }
               catch (Exception ex)
              {
                      throw ex;
              }
       }

       void LibraryInternal()
       {
               throw new Exception("Trace me if you can");
       }
}

Although exception was thrown in LibraryInternal() method console output will be following:
at ConsoleApplication6.Program.LibraryAPI() in D:\Users\andrii.khymenko\Development\ConsoleApplication6\ConsoleApplication6\Program.cs:line 35
at ConsoleApplication6.Program.ClientMethod() in D:\Users\andrii.khymenko\Development\ConsoleApplication6\ConsoleApplication6\Program.cs:line 19

By changing “throw ex;” to “throw;” in LibraryAPI() stack trace in console output will change to:
at ConsoleApplication6.Program.LibraryInternal() in D:\Users\andrii.khymenko\Development\ConsoleApplication6\ConsoleApplication6\Program.cs:line 41
at ConsoleApplication6.Program.LibraryAPI() in D:\Users\andrii.khymenko\Development\ConsoleApplication6\ConsoleApplication6\Program.cs:line 35
at ConsoleApplication6.Program.ClientMethod() in D:\Users\andrii.khymenko\Development\ConsoleApplication6\ConsoleApplication6\Program.cs:line 19

This difference in behavior has simple explanation: MSIL has two instructions “throw” and “rethrow” while C# has only one keyword “throw”. When code gets compiled all “throw;” lines end up with “rethrow” in MSIL which will keep original stack trace.

About khymenko

Developing for Windows and Windows Phone

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

I’m Tweeting

Follow

Get every new post delivered to your Inbox.