7

Possible Duplicate:
difference between throw and throw new Exception()

I'm a programmer working on adding new functionality to legacy code. While debugging, I parsed over this Catch block, which got an angry "object not set to reference of object" notice from Visual Studio:

catch(Exception ex)
            {
                SporeLog.Log("Failed to create new SavedDocumentList with Name: " + name, ex);
                throw;
            }

What does it mean to "throw". I'm familiar with throw new [exceptiontype]... but what does it mean to just... throw ?

Is this good practice, or should I alter this code to ease the trials of the developers after me?

And why does Visual Studio yell at me for doing this?

Community
  • 1
  • 1
Raven Dreamer
  • 6,940
  • 13
  • 64
  • 101
  • 1
    See [difference between throw and throw new Exception()](http://stackoverflow.com/questions/2999298/difference-between-throw-and-throw-new-exception). Basically, it lets you do something (e.g log in your example), then let the exception continue to propagate. Importantly, it doesn't break the stack trace. – Matthew Flaschen Jul 21 '10 at 16:34
  • While helpful, that doesn't explain why visual studio 2008 yells at me for this. I've edited my question to better reflect my original intent upon asking, as well as voting to reopen. – Raven Dreamer Jul 21 '10 at 17:01
  • The `throw` is not *causing* the `NullReferenceException`. As stated below in the answers, the `throw` statement re-throws the exception without resetting the StackTrace. If I understand the nuances of your question, the *original* exception was a NullReferenceException, which couldn't be *handled*, so the original coder logged it and rethrew it so it could potentially be handled elsewhere. – Toby Jul 23 '10 at 12:39

4 Answers4

12

Yes it is a good practice.... what it does is, it re-throws the same exception that it catched, keeping the stacktrace intact.

Community
  • 1
  • 1
Jaime
  • 6,736
  • 1
  • 26
  • 42
9

It means "re-throw this same exception". In other words, continue bubbling up the exception to the next try/catch block.

It's useful if you can't actually deal with an exception at this level, but want to log that the exception happened.

Unfortunately, many people think "log & rethrow" should be done at every level, leading to applications which run slowly, have log files with every exception logged multiple times, and often never actual handle the exception.

James Curran
  • 101,701
  • 37
  • 181
  • 258
3

throw; rethrows the original exception. This allows you to take some action at the current level, and then propagate the exception up the stack.

If the exception is the result of an implementation detail, it may be more appropriate to use exception-chaining to throw a domain-specific exception that wraps the original exception, to hide your clients from implementation details, and a plethora different exception types to catch.

If the exception makes sense to your clients, then rethrowing it is fine practice.

mdma
  • 56,943
  • 12
  • 94
  • 128
3

This is a good practice (sometimes). It allows you to catch an exception, log it or determine if it can be handled, then rethrow it without losing the StackTrace.

Your NullReferenceException came from SporeLog being null.

Toby
  • 7,354
  • 3
  • 25
  • 26
  • It could also be the reference to `name` that is null. – Philip Smith Jul 21 '10 at 16:38
  • @Philip, no. That would just be the same as str + "". – Matthew Flaschen Jul 21 '10 at 16:41
  • @Matthew - How do you know?? There is no info in the question as to what the type of name is. If name is a reference type and it has not been initialized it will generate the exception when accessed. If it is a value type and not initialized it would generate a different exception. – Philip Smith Jul 21 '10 at 16:58
  • @Philip, actually what I said should be true for a null reference of any type. And a default-initialized value type won't throw an exception here either. – Matthew Flaschen Jul 21 '10 at 17:55
  • @Matthew - Simply not true. If name is a null reference it does not have a ToString() method to call. Therefore it will throw an exception. There is no evidence in the question that the name variable has been initialized and if it has not it will throw an exception. So my original statement is true the exception could be caused by the name variable. – Philip Smith Jul 21 '10 at 18:03
  • @Philip, he's not calling `ToString` (*that* would cause an exception). "If an operand of string concatenation is null, an empty string is substituted." (http://msdn.microsoft.com/en-us/library/aa691375%28VS.71%29.aspx). Give me an example (for any type) of: `SomeType foo = null; "some string " + foo;` that causes an exception. – Matthew Flaschen Jul 21 '10 at 18:17
  • @Matthew - Wow, you learn something new everyday. I would have thought that this violates a founding principle of C# "Behaviour is predictable from first principles". Not throwing a exception when a null reference is accessed is unexpected. My point on ToString() is valid as your article reference confirms. – Philip Smith Jul 22 '10 at 07:51