Thursday, 13 November 2014

C#: Difference between “throw” and “throw ex” in C# .Net Exception

C#: Difference between “throw” and “throw ex” in C# .Net Exception

In day to day development, we all are very familiar with Exception  handling. We pretty much all know that we should wrap the code which may cause for any error in try/catch block and do something about error like give a error message to end user. Here I am not going to explain about Exceptionhandling in C#. Instead I am going to talk about a particular aspect of Exception  handling, which is"throw" vs "throw ex".

You can also find my other articles related to C#ASP.Net jQueryJava Script and SQL Server. I am writing this post because I was asked this question recently in a interview and unfortunately I didn't  know the answer. So I am posting this for those guys who uses "throw" and "throw ex" frequently but don't know the differences (not all,some knows).

Difference between “throw” and “throw ex”

Take a look on the below code snippest-
throw exthrow

?
1
2
3
4
5
6
7
8
try
{
   //Code which fails and raise the error
}
catch (Exception ex)
{
   throw ex;
}

?
1
2
3
4
5
6
7
8
try
{
   //Code which fails and raise the error
}
catch (Exception ex)
{
   throw;
}

Both the codes are perfectly reasonable and does the job. You can not get any difference in both of them until you are trying to debug the code to resolve the issue. That difference is the Stack Trace Information that gets sent with the exception
"When you throw an exception using "throw ex" then you override the original stack trace with a new stack trace that starts from the throwing method."

To understand it more clearly take a look an example for both the cases-
throw ex

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                MethodA();
            }
            catch (Exception ex)
            {
                //Showing overridden exception stack with MethodA instead of MethodB on top
                Console.WriteLine(ex.ToString());
            }
        }
 
        private static void MethodA()
        {
            try
            {
                MethodB();
            }
            catch (Exception ex)
            {
                //Overrides original stack trace
                throw ex;
            }
        }
 
        private static void MethodB()
        {
            throw new NotImplementedException();
        }
    }
}
In the above code you can see that I have called a function "MethodA()" which calls another function"MethodB()"MethodB() raises an exception which is caught by MethodA() andMethodA()throws the exception with Exception object "ex". Now take a look on the output of the above code.

stack trace of "throw ex" in Exception
Here you can see that stack string shows the MethodA() instead of MethodB() on the top. Which is not the right function which raised the exception.

Now change the previous code little bit.
throw ex

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                MethodA();
            }
            catch (Exception ex)
            {
                //Showing original exception stack with MethodB on top
                Console.WriteLine(ex.ToString());
            }
        }
 
        private static void MethodA()
        {
            try
            {
                MethodB();
            }
            catch (Exception ex)
            {
                //Keeps original stack trace
                throw;
            }
        }
 
        private static void MethodB()
        {
            throw new NotImplementedException();
        }
    }
}
Now I have replaced "throw ex;" with "throw;" in MethodA().After this change, now take a look on the new output.
stack trace of "throw" in Exception
Now you can see here, new stack string shows the MethodB() on the top and then MethodA() andMain() method.

No comments:

Post a Comment