Search code examples
c#exceptionc#-4.0try-catchthrow

How to throw an exception


What are the best practices for choosing between throw; and throw ex;? Is there any at all? Regarding, for example, this simple snippet:

try{
    // some code
} catch (Exception ex) {
    // some catcher code
    // throw; ?
    // or
    // throw ex; ?
    // how to decide which one?
}

I know the difference between the two above. How can I decide to use one of them? Is there a best practice to making a better choice?


Solution

  • It's very simple.

    Do you want to keep the stack trace to see exactly where the exception occurs? Then use throw. This will be like if you don't use catch at all.

    Do you only care about the current method's debug information? Then use throw ex.

    To demonstrate:

    static void Main(string[] args)
    {
        try
        {
            Test();
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }
    
    static void Test()
    {
        try
        {
            // long lambda chain
            new Action(() => new Action(() => new Action(() => { throw new InvalidOperationException(); })())())();
        }
        catch (Exception ex)
        {
            //throw;
            //throw ex;
        }
    }
    

    throw will keep the stack trace:

    System.InvalidOperationException: Operation is not valid due to the current state of the object.
        at ConsoleApplication.Program.<>c.<Test>b__1_2() in ConsoleApplication\Program.cs:line 22
        at ConsoleApplication.Program.<>c.<Test>b__1_1() in ConsoleApplication\Program.cs:line 22
        at ConsoleApplication.Program.<>c.<Test>b__1_0() in ConsoleApplication\Program.cs:line 22
        at ConsoleApplication.Program.Test() in ConsoleApplication\Program.cs:line 26
        at ConsoleApplication.Program.Main(String[] args) in ConsoleApplication\Program.cs:line 13
    

    throw ex will reset stack trace:

    System.InvalidOperationException: Operation is not valid due to the current state of the object.
        at ConsoleApplication.Program.Test() in ConsoleApplication\Program.cs:line 27
        at ConsoleApplication.Program.Main(String[] args) in ConsoleApplication\Program.cs:line 13
    

    As for best practices - the choice is usually throw. As a developer, you want to get as much information as you can. throw ex is a counterpart - some information is hidden, but maybe you want to hide it, who knows?