What is the difference between “throw” and “throw ex” in C#?
The difference between “throw” and “throw ex” is that “throw” preserves the stack trace while ”throw ex” does not preserve the stack trace.
We don’t always want to handle an exception and let the program continue after catching it. Sometimes we want the exception to move on and perhaps be caught in the next catch clause, but we want to log something or do any other action related to this exception occurrence. This is what is referred to as re-throwing an exception. We can do it by either using “throw” or “throw ex”.
The difference between them is that:
- “throw” preserves the stack trace (the stack trace will point to the method that caused the exception in the first place)
- “throw ex” does not preserve the stack trace (we will lose the information about the method that caused the exception in the first place. It will seem like the exception was thrown from the place of its catching and re-throwing)
Firstly, let’s ensure that we have a clear understanding of what a stack trace is.
What is stack trace?
A stack trace is a record of all methods that have been called and resulted in a specific moment in code. Let’s consider the following code:
Console.WriteLine("What is stack trace?");
FirstMethod();
static void FirstMethod()
{
Console.WriteLine("In first method");
SecondMethod();
}
static void SecondMethod()
{
Console.WriteLine("In second method");
ThirdMethod();
}
static void ThirdMethod()
{
Console.WriteLine("In third method");
Console.WriteLine(Environment.StackTrace);
Console.WriteLine();
}
As you can see FirstMethod calls SecondMethod which calls ThirdMethod. In the ThirdMethod we log the current state of the stack trace.
Let’s see what will be printed to the console if I call FirstMethod from the Main method of the program:
The method that has been called most recently is displayed at the top of the stack trace, while the one that has been called first is displayed at the bottom. The stack trace stores the information about all method calls that lead to the current moment in the program execution. As you can see the getter of the Environment. StackTrace property is at the very top because we read the stack trace with this method exactly, so it’s the latest to be called. Please note that also the numbers of lines of code where those methods have been called are stored in the stack trace.
Stack trace has many uses, but for us as developers the most important value it brings is that it helps us track where some exceptions happened. Imagine that you have a huge app, and when it throws an exception all it says is “object is null!”. That wouldn’t be very helpful. We want to know the exact method that caused the problem, and even more — the exact line. This will help us to take a look at the right place, place a breakpoint there, and overall solve the problem easier and faster.
After learning the concept of stack trace, we can continue our main topic from where we left off.
Throw vs Throw Ex
We mentioned that ‘throw’ preserves the stack trace, while ‘throw ex’ does not. This is sometimes known as “Resetting the stack trace”. Let’s examine the code that will display the difference:
Here is the first method. As you can see it’s designed to throw an exception (it will try to access the first number of an empty collection).
And here is the Throw Ex method and its caller method. It is almost the same, but doing “throw ex” instead of throw.
Now. Let’s see the output of the programs.
For throw, the stack trace ends at Linq.ThrowHelper.ThrowNoElementsException.
For throw ex, the stack trace ends at MethodThrowEx line 27, which is exactly this line:
This means that all information that has been stored in the stack trace before reaching the “throw ex” command is lost.
This is not good for us, as we lose valuable data about the origins of the exception.
Let’s summarize.
The difference between “throw” and “throw ex” is that “throw” preserves the stack trace (the stack trace will point to the method that caused the exception in the first place) while ”throw ex” does not preserve the stack trace (we will lose the information about the method that caused the exception in the first place. It will seem like the exception was thrown from the place of its catching and re-throwing).
Source Code
You can access the source code of the project on my GitHub account. If you can give the repository a star and share the article, you will support me in reaching more people.
👏 If you found the content useful, I would appreciate it if you could support it with applause (you can also contribute with more than one applause by holding down the clap button for a long time).
⬇️ Check out my other articles.
💬 Let me know in the comment section what have I missed? Where I was wrong?
👨👦👦 You can also share this article with your friend. Argue a little on it. It is known that the truth is born in a dispute.
🙃 Stay determined, stay focused, and keep going
Thanks for reading…