views:

5679

answers:

11

Duplicate: http://stackoverflow.com/questions/22623/net-throwing-exceptions-best-practices

I have a question for you that stems from my partner doing things a different way than I do.

Is it better to do this :

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

or this:

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

Do they do the same thing? Is one better than the other?

+70  A: 

you should always use

throw;

To rethrow an exception else you'll stomp the stack trace. If you print the trace resulting from "throw ex" you'll see that it ends on that statement and not att the real source of the exception.

Basicly it should be deemed a criminal offense to use "throw ex".

Torbjörn Gyllebring
There is an fxcop rules for that: RethrowToPreserveStackDetailshttp://msdn.microsoft.com/en-us/library/ms182363(VS.80).aspx
madgnome
+7  A: 

The first preserves the original stack trace of the exception, the second one replaces it with the current location.

Therefore the first is BY FAR the better.

Quibblesome
+2  A: 

The first is better. If you try to debug the second and look at the call stack you won't see where the original exception came from. There are tricks to keep the call-stack intact (try search, it's been answered before) if you really need to rethrow.

Mendelt
+2  A: 

Duplicate http://stackoverflow.com/questions/22623/net-throwing-exceptions-best-practices

Sam Saffron
Haven't see it, they need to work on the search feature, doesn't work pretty well.
Daok
+18  A: 

My preferences is to use

try 
{
}
catch (Exception ex)
{
     ...
     throw new Exception ("Put more context here", ex)
}

This preserves the original error, but allows you to put more context, such as an object ID, a connection string, stuff like that. Often my exception reporting tool will have 5 chained exceptions to report, each reporting more detail.

RB
Is this just an example or do you always throw the Exception object, which you shouldn't do? Also, you can add the extra information to the Data property on the original exception and not lose any of the original context.
Austin Salonen
Typically I will be throwing specific BusinesssLayer Exceptions (e.g. BusinessObjectInstantionFailed sort of thing). I prefer chained Exceptions, because I would expect most other developers to assume exceptions might be chained, but they might not interrogate other properties.
RB
+3  A: 

If you throw an exception with a variable (the second example) the StackTrace will include the original method that threw the exception.

In the first example the StackTrace will be changed to reflect the current method.

Example:

static string ReadAFile(string fileName) {
    string result = string.Empty;
    try {
        result = File.ReadAllLines(fileName);
    } catch(Exception ex) {
        throw ex; // This will show ReadAFile in the StackTrace
        throw;    // This will show ReadAllLines in the StackTrace
    }
A: 

My answer is a question:

Imagine you want to do something like:

catch(TargetInvocationException ex)
{
   throw ex.InnerException; 
}

Is there a way to preserve the InnerException' stack trace instead of replacing it with the current location?

Olmo
Yes, throw it wrapped in a new exception: throw new MyException("some error", ex.InnerException). You can't throw the inner exception itself though.
TheSoftwareJedi
+1  A: 

It depends. In a debug build, I want to see the original stack trace with as little effort as possible. In that case, "throw;" fits the bill. In a release build, however, (a) I want to log the error with the original stack trace included, and once that's done, (b) refashion the error handling to make more sense to the user. Here "Throw Exception" makes sense. It's true that rethrowing the error discards the original stack trace, but a non-developer gets nothing out of seeing stack trace information so it's okay to rethrow the error.

        void TrySuspectMethod()
        {
            try
            {
                SuspectMethod();
            }
#if DEBUG
            catch
            {
                //Don't log error, let developer see 
                //original stack trace easily
                throw;
#else
            catch (Exception ex)
            {
                //Log error for developers and then 
                //throw a error with a user-oriented message
                throw new Exception(String.Format
                    ("Dear user, sorry but: {0}", ex.Message));
#endif
            }
        }

The way the question is worded, pitting "Throw:" vs. "Throw ex;" makes it a bit of a red-herring. The real choice is between "Throw;" and "Throw Exception," where "Throw ex;" is an unlikely special case of "Throw Exception."

Perry Tribolet
A: 

I am from JAVA Background,i want to know if we throw the exception by any statement like throw; or throw ex; Should we handle this exception somewhere? I mean should i catch this exception... void TrySuspectMethod() { try { SuspectMethod(); }

if DEBUG

        catch
        {
            //Don't log error, let developer see 
            //original stack trace easily
            throw;

else

      }

}

void SuspectMethod() { try{ # do something } finally { //..............

      }

} Should i catch the rethrow ex from TrySuspectMethod() in SuspectMethod() method?

A: 

You should always use "throw;" to rethrow the exceptions in .NET,

Refer this, http://weblogs.asp.net/bhouse/archive/2004/11/30/272297.aspx

Basically MSIL (CIL) has two instructions - "throw" and "rethrow" and C#'s "throw ex;" gets compiled into MSIL's "throw" and C#'s "throw;" - into MSIL "rethrow"! Basically I can see the reason why "throw ex" overrides the stack trace.

Vinod T. Patil
A: 

Here is article that explains difference between "throw" and "throw ex" http://patelshailesh.com/index.php/difference-between-throw-and-throw-ex

shailesh