Catch Clause or: Crap! There is something I don’t know about C#.

October 18th, 2008 by jason Leave a reply »

I first started programming .Net in 2000.  I got my hands on the Beta 2 version of .Net 1.0.  In those days I was programming in VB6, so VB.Net seemed like the best choice.  But a couple of weeks after downloading the beta I was in a book store and saw a C# book.  I picked it up and started thumbing through it.  I remember I said something out loud like, “Wow, this is just like Java!” I had programmed in Java for a while as well, and had a background in C/C++. I preferred the syntax greatly to that of VB.  From there on out I tried to do all my .Net stuff in C#.

I recount this tale because I so rarely find something in C# I don’t know or understand. This is bragging. Its just the reality of getting to know a language/environment over several years. 

Of course there are new language features released every year or two that I have to work to learn.  But all in all, the language isn’t much of a mystery to me.  So yesterday when a coworker told me I was using a throw statement in a catch clause wrong, I was very surprised.  I was doing something like:

try
{
  ...
  SomethingThatMyThrowEx();
}
catch(Exception ex)
{
  ...
  throw ex;
}

So what is wrong with this? I didn’t see anything wrong at all. I wanted to catch the exception, take some action, and simply re-throw the exception. And this code will do that. The problem is, the exception will have a new stack trace from the point at which I re-throw it. Why? Because the throw statement takes and expression, not an object. The “ex” object in this case is being used as an expression of how the exception should look when thrown. This seems really strange, but it is in the C# language spec. Crap, how did I miss this all these years!

When C#/.Net executes the throw line it uses the exception object as an expression of how the expression should be thrown, and ads a stack trace from the current location in code. The previous stack trace is gone.

So how do we preserve the stack trace? We use only the throw keyword with no expression. This instructs .Net to simply continue the exception bubble-up process:


try
{
  ...
  SomethingThatMyThrowEx();
}
catch(Exception ex)
{
  ...
  throw; //no ex
}

Pretty simple, and pretty damn subtle. I won’t forget that one!

Advertisement

Leave a Reply

You must be logged in to post a comment.