Random header image... Refresh for more!

Posts from — December 2010

Just throw;ing this out there.

In C#, what’s the difference between “throw;” and “throw e;”?

This is one of those “Interview Question” tidbits of language trivia.  It’s the sort of thing that you can probably remember the exact circumstances where you learned about it, because it was probably preceded by three hours of frustration and confusion.  It’s the sort of thing that I’d always assumed separated the serious C# programmers from the casual passerby.

Until today…

Today, this issue came up and I was honestly surprised by the number of people around me who didn’t know the difference, and even more surprised about how the difference seems to be missing from official sources, like the C# Language Specification1, so I felt compelled to write about it.

To clarify, I’m asking about the difference between “throw;” and “throw e;”, where you’re rethrowing an exception that was caught inside a catch statement.

In other words, this:

public static void DoSomething()
{
    throw new Exception("Thrown on line 12.");
}

public static void ExceptionRethrower()
{
    try
    {
        DoSomething();
    }
    catch (Exception e)
    {
        LogException(e);
        throw e;
    }
}

So, DoSomething(); does something and throws an exception2.  You want to catch it and log it or whatever, but you want the exception to bubble up to the callers of ExceptionRethrower() for some reason.  I’m sure you’ve written code like this somewhere.

And there it is, “throw e;” at the end of the catch.  Let’s write a bit of code to call this function and catch the exception, and see what turns up.

static void Main(string[] args)
{
    try
    {
        ExceptionRethrower();
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
    }
}

Okay…  So, the function DoSomething is throwing an exception, which is caught and logged in ExceptionRethrower, then rethrown up to Main, where the exception and its stack trace are printed out.  That means the stack trace will have DoSomething on top, then ExceptionRethrower, followed by Main on the bottom, right?

System.Exception: Thrown on line 12.
   at ThrowExample.Program.ExceptionRethrower() in E:\svn\Projects\ThrowExample\ThrowExample\Program.cs:line 26
   at ThrowExample.Program.Main(String[] args) in E:\svn\Projects\ThrowExample\ThrowExample\Program.cs:line 34

Nope.

It’s got Main and ExceptionRethrower, but what happened to DoSomething?  And the exception message says that I threw it on line 12, but according to the stack trace, I was nowhere near line 12.

So…  WTF?

Let’s play with the debugger, instead.  I’m going to comment out the try/catch in Main and let the exception fall out and kill my app and see what VS has to say about it.

Line 26 is my “throw e;”.  It’s eating my stack trace!

Okay, so, let’s see what happens if I just “throw;”, instead.

System.Exception: Thrown on line 12.
   at ThrowExample.Program.DoSomething() in E:\svn\Projects\ThrowExample\ThrowExample\Program.cs:line 12
   at ThrowExample.Program.ExceptionRethrower() in E:\svn\Projects\ThrowExample\ThrowExample\Program.cs:line 26
   at ThrowExample.Program.Main(String[] args) in E:\svn\Projects\ThrowExample\ThrowExample\Program.cs:line 34

Hey, look!  DoSomething() is there in the trace now, with the exception originating on line 12 like it should.

So, there’s your answer to the original question:  Rethrowing the instance, as in “throw e;” will discard the existing stack trace and make it look like the exception originated on the “throw e;” line, while a parameterless “throw;” will retain the original stack trace.

Sort of…

Look at that second stack trace again.  Look closely at the line numbers.  It still has line 26, where the “throw;” is located, but the call to DoSomething() is on line 21.  It should, like the call stack below shows, have DoSomething() line 12 (Where the exception was thrown), then ExceptionRethrower() line 21 (Where DoSomething() was called), then Main() line 34 (Where ExceptionRethrower() was called).

How did line 21 get tossed aside for line 26?  Well, think about the stack for a moment.  When you’re generating a stack trace, either on the call stack side or on the exception side, each function has a single frame, pointing at the last line that was executed.  When you’re at line 12 in DoSomething(), the last line in ExceptionRethrower() was line 21.  However, once the exception is thrown, you hit the catch in ExeceptionRethrower() and get rerouted, so by the time you end up in Main(), the last line called in ExceptionRethrower() was line 26 at the throw;.  This also means that if you throw, catch, and rethrow, all in a single function, the stack trace will end up pointing at the rethrow, regardless of whether you’re using “throw;” or “throw e;”.

Of course, if that whole “call stack” explanation I just gave actually held any water, then adding in a finally block would cause the stack trace to point at the last line of the finally, because that was the last line of the function executed.  However, that’s not the case.  Even when you add in the finally, the stack trace still points at the throw line.   But hey, the explanation still sounds plausible, so I’m leaving it in this post.  I’m sure it’s something close to that, anyway.  It’s a good thing finallys don’t affect the trace, because if it did, I can’t imagine how wildly FUBARed some stack traces would end up. 3

In general, if you have to catch and rethrow an exception, you should use the plain throw;.  If you rethrow the instance using throw e;, you’ll have a hard time debugging and testing, because your stack traces will all dead end at a throw that’s nowhere near the source of the problem.  However, if you’re writing a library or service for third-party consumption, then throw e; provides a quick way to let exceptions get out to the callers while hiding some of the implementation details of your code by killing off the call stack. 4

Another thing to be aware of is that whichever rethrowing scheme you use, the original instance is used.  That means that if you save off the exception instance for later, the stack trace will have been wiped out or modified by the time you want to use it.  Even more subtle and insidious is that this means that if you’re using a threaded logger of some sort, there’s a chance that the stack trace will be mangled by the time the logger gets around to writing out the exception.  In other words, some times the log will say the exception’s on line 12, other times it’ll say the exception’s on line 26. 5

The sample code is here: http://www.mathpirate.net/svn/Projects/ThrowExample/

To reiterate, for those who skipped to the end:

  • “throw e;” wipes out the stack trace, restarting it at the point of the throw.
  • “throw;” maintains the existing stack trace, but still mangles the stack of the current frame.
  1. I couldn’t find it in there, anyway… []
  2. From line 12, obviously… []
  3. By the way, speaking of finally blocks, did you know that you can’t return from one?  There’s another bit of obscure language trivia for you. []
  4. Of course, if you actually think that’s a good idea, then you probably will want to rethink your exception handling strategy in general…  That’s just the only reason I could think of for deliberately using throw e; to rethrow a caught exception. []
  5. Have fun debugging that one… []

December 13, 2010   No Comments

Straight to the Source

http://mathpirate.net/svn/Android/AndroidExperiment/

And here’s the project in SVN.  I think.  Enjoy.

December 12, 2010   No Comments

Binary.

I don’t actually know how any of this works, but here you go, if this is what I’m supposed to give you:  http://www.mathpirate.net/log/UploadedFiles/AndroidExperiment/AndroidExperiment.apk

It hasn’t really been tested, it might not be up to date, and I don’t even know if just giving you that file will work.  Enjoy!

Now I have to figure out how to get all of this stuff checked into SVN, because Eclipse seems to be openly hostile regarding the concept of putting things in a source repository. 1

  1. Although that could just be because I don’t understand Eclipse workspaces yet… []

December 12, 2010   No Comments

I Think It’s Going To Kill Us All…

Audio File Of Insanity

I think I’d better fix that bug.

Then add a feature to support this mode because it’s so awesome like this…

December 12, 2010   No Comments

I Don’t Think That Worked…

Ah crap, it’s gone rampant!  Where is my Spartan Laser…?

December 12, 2010   No Comments

Let’s Start a Dialog

.Net:

if(MessageBox.Show("Are You Sure?", MessageBoxButtons.YesNo) == DialogResult.Yes) { DoWork(); }

Android:

     AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
     dialogBuilder.setTitle("Save File");
     dialogBuilder.setMessage("Are you sure?");
     dialogBuilder.setPositiveButton("Yes",
       new DialogInterface.OnClickListener()
       {
        public void onClick(DialogInterface dialog, int which)
        {
         doWork();
        }
       });
     dialogBuilder.setNegativeButton("No",
       new DialogInterface.OnClickListener()
       {
        public void onClick(DialogInterface dialog, int which)
        {
         dontDoWork();
        }
       });
     dialogBuilder.setCancelable(true);
     dialogBuilder.setOnCancelListener(
       new DialogInterface.OnCancelListener() {
     
     public void onCancel(DialogInterface dialog)
     {
      dontDoWorkHereEither();
     }
    });
     dialogBuilder.show();

OMG.  WTF.  SERIOUSLY?

Why write just one line of code when TWENTY-NINE will do the same thing just as well?

December 12, 2010   No Comments

I’m Sorry, Java…

I’m sorry, Java.  I forgot to IMPORT EVERY SINGLE CLASS IN THE ENTIRE UNIVERSE.

I’m sorry, Java.  I forgot to DECLARE THAT I THROW EVERY SINGLE EXCEPTION CLASS IN THE ENTIRE UNIVERSE.

December 12, 2010   No Comments

Android Launch

December 12, 2010   No Comments

Ew…. I feel dirty now.

I just realized what this reminds me of.  Some of this Android stuff feels like MFC.  That’s why it’s tripping my icky sensors.  I have to register event messages in one file, then I have to make a big and ugly switch statement in another file that dispatches my actions using magic constants.

December 11, 2010   No Comments

Summarizing Android

So far, my experience with Android has been brief moments of totally awesome brilliance, separated by vast swaths of WTF.

For example, why is it easier to get a speech synthesizer integrated into my application than it is to get a context menu set up?  Why is the debugger so introverted that it refuses to tell me what’s wrong?  W…h…y… …i…s… …i…t… …s…o… …s…l…o…w… …t…o… …t…y…p…e… …a…n…y…t…h…i…n…g… …i…n… …t…h…e… …e…m…u…l…a…t…o…r…?…

I understand that writing a single application meant to run on multiple different highly contstrained environments is complicated.  I understand that defining a View in XML and interacting with compiled code classes is complicated.

But Microsoft’s done it and has done it for years.  I set some things in a XAML file and it’s just there in the class.  I don’t have to use a TextBox Resource ID to look up an element I need to work with.  And I doubt they’re the first or the only that can do it.  Why can’t the flagship open source IDE figure that out?

I’m hoping that I’m just missing something.

Whatever.  At least it’s still not Objective C.

December 11, 2010   No Comments