29

Are these two code examples the same? Catch and Catch (Exception e) have the same output, and the result is also the same if I write Throw or Throw e.

Main:

try
{
    A();
    //B();
}
catch (Exception e)
{
    Console.WriteLine("{0} exception caught.", e);
}

Code 1:

static void A()
{
    try
    {
        int value = 1 / int.Parse("0");
    }
    catch (Exception e)
    {
        throw e;
    }
}

Code 2:

static void A()
{
    // Rethrow syntax.
    try
    {
        int value = 1 / int.Parse("0");
    }
    catch
    {
        throw;
    }
}
DanM7
  • 2,203
  • 3
  • 28
  • 46
a1204773
  • 6,923
  • 20
  • 64
  • 94
  • Both are the same because you `throw`. – JonH May 29 '12 at 20:12
  • @MarcGravell - Marc yes if he `throws e` there is a difference. – JonH May 29 '12 at 20:15
  • Got it, I just wanted to re-tag but I see that has already been taken care of! – Jeshurun May 29 '12 at 20:15
  • What is the point of `throw e`, as you throw the exception but with the the useful part of stacktrace missing – Chris S May 29 '12 at 20:16
  • @JonH already deleted my comment - misread the question ;p – Marc Gravell May 29 '12 at 20:16
  • @MarcGravell It was updated by Paul, was missing tag before that. – eandersson May 29 '12 at 20:16
  • @MarcGravell isnt it amazing how fast people read the comments / posts and post back. – JonH May 29 '12 at 20:17
  • Somewhere on here this is a duplicate question - just cant find it. – JonH May 29 '12 at 20:18
  • possible duplicate of [Is there a difference between "throw" and "throw ex"?](http://stackoverflow.com/questions/730250/is-there-a-difference-between-throw-and-throw-ex) – spender May 29 '12 at 20:22
  • @spender the difference is actually `catch` vs `catch(Exception ex)` – Marc Gravell May 29 '12 at 20:24
  • @MarcGravell catch and catch(Exception ex) is practically the same right? As they will both catch all exceptions, but the latter one will allow you to use the information? like logg it etc – eandersson May 29 '12 at 20:27
  • @Fuji - They both will catch the exception being thrown. The difference is the first condition `catch(Exception ex)` has a reference to an exception, namely `ex`, while the second doesn't. – JonH May 29 '12 at 20:33
  • @Fuji in .NET 1.1 with unmanaged exceptions, it could be different. Doesn't really happen any more though, – Marc Gravell May 29 '12 at 21:30

2 Answers2

58

I think there are two questions here.


What is the difference between throw and throw e;?

I don't think there is ever a good reason to write catch (Exception e) { throw e; }. This loses the original stacktrace. When you use throw; the original stacktrace is preserved. This is good because it means that the cause of the error is easier to find.


What is the difference between catch and catch (Exception e)?

Both of your examples are the same and equally useless - they just catch an exception and then rethrow it. One minor difference is that the first example will generate a compiler warning.

The variable 'e' is declared but never used

It makes more sense to ask this question if you had some other code in your catch block that actually does something useful. For example you might want to log the exception:

try
{
    int value = 1 / int.Parse("0");
}
catch (Exception e)
{
    LogException(e);
    throw;
}

Now it's necessary to use the first version so that you have a reference to the caught exception.

If your catch block doesn't actually use the exception then you would want to use the second version to avoid the compiler warning.

Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
  • I updated the code I just wanted to know if its matter to write Exception e / Throw e because the result is same.. – a1204773 May 29 '12 at 20:22
  • 1
    @Loclip: If you care about not losing the stacktrace, and if you care about not having compiler warnings when you compile your code (and you *should* care about these things) then, yes, it does matter. – Mark Byers May 29 '12 at 20:25
  • 3
    It's also possible to specify the exception type to catch without introducing a local variable (which the compiler complains is never used). You just say: `catch (ArithmeticException) { ... }` – Jeppe Stig Nielsen Jun 27 '12 at 14:20
39

If we ignore the "unused variable" warning, the only time there is a practical difference between

catch {...}

and

catch(Exception ex) {...}

is when some non-C# code is throwing a non-Exception exception. C++ can throw anything. In .NET 1.1, you had to use catch (no (Exception ex)) to handle these unusual exceptions. However, this was problematic - not least, you can't see what was thrown! So in .NET 2.0 and above this is wrapped by default, so even if C++ throws, say, a string - you see it as an Exception subclass. Note that this can be disabled via a configuration setting, but: don't. Leave it alone!

The issue of throw; vs throw ex; is already mentioned, and relates to stack-traces. You can use throw in both cases, causing the original stack-trace to be preserved.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • For purely educational purposes, do you have a link for further information on this configuration setting? Or if you do not wish to tempt fate by linking it here, may I DM you on twitter? I am currently unable to find out more information about it. – Lukazoid Apr 10 '15 at 09:45
  • 1
    Another practical concern- if I don't have "catch(Exception ex) {...}" then I won't know what the exception is when I am debugging. Unless I am mistaken and there is a way to see the exception in empty "catch{..}" statements... – ORcoder Feb 21 '18 at 16:24
  • This has been available for a while, but you can use `$exception` in the watch window: https://stackoverflow.com/questions/15943373/how-to-see-exception-detail-in-debugger-without-assigning-variable-to-exception – CodeNaked Dec 17 '19 at 16:20
  • Or you can see it in the 'Locals' tab. – Mike Rosoft Aug 10 '20 at 08:11