Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a difference between "throw" and "throw ex"?

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?

like image 523
dance2die Avatar asked Apr 08 '09 14:04

dance2die


People also ask

What is the difference between throw exceptions and throw clauses?

The basic difference is that the Throw exception overwrites the stack trace and this makes it hard to find the original code line number that has thrown the exception. Throw basically retains the stack information and adds to the stack information in the exception that it is thrown.

What is the difference between throw and throws statement in Java?

Throw is a keyword which is used to throw an exception explicitly in the program inside a function or inside a block of code. Throws is a keyword used in the method signature used to declare an exception which might get thrown by the function while executing the code.

What is throw statement in C#?

In c#, the throw is a keyword, and it is useful to throw an exception manually during the execution of the program, and we can handle those thrown exceptions using try-catch blocks based on our requirements. The throw keyword will raise only the exceptions that are derived from the Exception base class.


2 Answers

Yes, there is a difference;

  • throw ex resets the stack trace (so your errors would appear to originate from HandleException)
  • throw doesn't - the original offender would be preserved.

    static void Main(string[] args) {     try     {         Method2();     }     catch (Exception ex)     {         Console.Write(ex.StackTrace.ToString());         Console.ReadKey();     } }  private static void Method2() {     try     {         Method1();     }     catch (Exception ex)     {         //throw ex resets the stack trace Coming from Method 1 and propogates it to the caller(Main)         throw ex;     } }  private static void Method1() {     try     {         throw new Exception("Inside Method1");     }     catch (Exception)     {         throw;     } } 
like image 154
Marc Gravell Avatar answered Oct 06 '22 08:10

Marc Gravell


(I posted earlier, and @Marc Gravell has corrected me)

Here's a demonstration of the difference:

static void Main(string[] args) {     try {         ThrowException1(); // line 19     } catch (Exception x) {         Console.WriteLine("Exception 1:");         Console.WriteLine(x.StackTrace);     }     try {         ThrowException2(); // line 25     } catch (Exception x) {         Console.WriteLine("Exception 2:");         Console.WriteLine(x.StackTrace);     } }  private static void ThrowException1() {     try {         DivByZero(); // line 34     } catch {         throw; // line 36     } } private static void ThrowException2() {     try {         DivByZero(); // line 41     } catch (Exception ex) {         throw ex; // line 43     } }  private static void DivByZero() {     int x = 0;     int y = 1 / x; // line 49 } 

and here is the output:

Exception 1:    at UnitTester.Program.DivByZero() in <snip>\Dev\UnitTester\Program.cs:line 49    at UnitTester.Program.ThrowException1() in <snip>\Dev\UnitTester\Program.cs:line 36    at UnitTester.Program.TestExceptions() in <snip>\Dev\UnitTester\Program.cs:line 19  Exception 2:    at UnitTester.Program.ThrowException2() in <snip>\Dev\UnitTester\Program.cs:line 43    at UnitTester.Program.TestExceptions() in <snip>\Dev\UnitTester\Program.cs:line 25 

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() and ThrowException2() is the line number of the throw statement, not the line number of the call to DivByZero(), which probably makes sense now that I think about it a bit...

Output in Release mode

Exception 1:

at ConsoleAppBasics.Program.ThrowException1() at ConsoleAppBasics.Program.Main(String[] args) 

Exception 2:

at ConsoleAppBasics.Program.ThrowException2() at ConsoleAppBasics.Program.Main(String[] args) 

Is it maintains the original stackTrace in debug mode only?

like image 29
Shaul Behr Avatar answered Oct 06 '22 10:10

Shaul Behr