There are some posts that asks what the difference between those two are already.
(why do I have to even mention this...)
But my question is different in a way that I am calling "throw ex" in another error god-like handling method.
public class Program {
public static void Main(string[] args) {
try {
// something
} catch (Exception ex) {
HandleException(ex);
}
}
private static void HandleException(Exception ex) {
if (ex is ThreadAbortException) {
// ignore then,
return;
}
if (ex is ArgumentOutOfRangeException) {
// Log then,
throw ex;
}
if (ex is InvalidOperationException) {
// Show message then,
throw ex;
}
// and so on.
}
}
If try & catch
were used in the Main
, then I would use throw;
to rethrow the error.
But in the above simplied code, all exceptions go through HandleException
Does throw ex;
has the same effect as calling throw
when called inside HandleException
?
No, this will cause the exception to have a different stack trace. Only using a
throw
without any exception object in thecatch
handler will leave the stack trace unchanged.You may want to return a boolean from HandleException whether the exception shall be rethrown or not.
Look at here: http://blog-mstechnology.blogspot.de/2010/06/throw-vs-throw-ex.html
Throw:
It preserve the Stack information with Exception
This is called as "Rethrow"
If want to throw new exception,
Throw Ex:
It Won't Send Stack information with Exception
This is called as "Breaking the Stack"
If want to throw new exception,
To give you a different perspective on this, using throw is particularly useful if you're providing an API to a client and you want to provide verbose stack trace information for your internal library. By using throw here, I'd get the stack trace in this case of the System.IO.File library for File.Delete. If I use throw ex, then that information will not be passed to my handler.
(I posted earlier, and @Marc Gravell has corrected me)
Here's a demonstration of the difference:
and here is the output:
You can see that in Exception 1, the stack trace goes back to the
DivByZero()
method, whereas in Exception 2 it does not.Take note, though, that the line number shown in
ThrowException1()
andThrowException2()
is the line number of thethrow
statement, not the line number of the call toDivByZero()
, which probably makes sense now that I think about it a bit...Output in Release mode
Exception 1:
Exception 2:
Is it maintains the original stackTrace in debug mode only?
The other answers are entirely correct, but this answer provides some extra detalis, I think.
Consider this example:
If you uncomment the
throw arithExc;
line, your output is:Certainly, you have lost information about where that exception happened. If instead you use the
throw;
line, this is what you get:This is a lot better, because now you see that it was the
Program.Div
method that caused you problems. But it's still hard to see if this problem comes from line 35 or line 37 in thetry
block.If you use the third alternative, wrapping in an outer exception, you lose no information:
In particular you can see that it's line 35 that leads to the problem. However, this requires people to search the
InnerException
, and it feels somewhat indirect to use inner exceptions in simple cases.In this blog post they preserve the line number (line of the try block) by calling (through reflection) the
internal
intance methodInternalPreserveStackTrace()
on theException
object. But it's not nice to use reflection like that (the .NET Framework might change theirinternal
members some day without warning).let's understand the difference between throw and throw ex. I heard that in many .net interviews this common asked is being asked.
Just to give an overview of these two terms, throw and throw ex are both used to understand where the exception has occurred. Throw ex rewrites the stack trace of exception irrespective where actually has been thrown.
Let's understand with an example.
Let's understand first Throw.
output of the above is below.
shows complete hierarchy and method name where actually the exception has thrown.. it is M2 -> M2. along with line numbers
Secondly.. lets understand by throw ex. Just replace throw with throw ex in M2 method catch block. as below.
output of throw ex code is as below..
You can see the difference in the output.. throw ex just ignores all the previous hierarchy and resets stack trace with line/method where throw ex is written.