80

What is the difference between:

catch
{
    MessageBox.Show("Error.");
}

and:

catch (Exception ex)
{
    MessageBox.Show("Error.");
    //we never use ex, so is it better to use catch without arguments?
}
Christos
  • 53,228
  • 8
  • 76
  • 108
petko_stankoski
  • 10,459
  • 41
  • 127
  • 231
  • 1
    In the second case, use `catch (Exception)` if you want to catch that type or derived types of exceptions, but don't want to know the details. Otherwise you'll get a warning and declare a variable when one isn't needed – Kieren Johnstone Nov 04 '11 at 13:23

5 Answers5

95

As of .NET 2, if you don't tweak the configuration? Nothing.

Before then, or with some config tweak I can't remember precisely, there was the possibility of an exception being thrown from unmanaged code which didn't get converted into an Exception-compatible object.

Note that there's another option in between, where you specify the type but no variable:

catch (Exception)
{
   ...
}

Personally I'd be very wary of catching an exception without even logging it. It may be required if you're calling a boneheaded API, but it's generally best avoided.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    "there was the possibility of an exception being thrown from unmanaged code which didn't get ..." So from 2.0 onward it gets converted to Exception compatible ? i.e. now anything thrown by managed or unmanaged will be caught by catch (Exception e){} as well. Btw, I did try to experiment with Outlook Interop Library but not sure how to get a legimate unmanaged code error. – devanalyst May 18 '13 at 14:43
  • 1
    @devanalyst: Yes, I *believe* everything is converted to `Exception` now. – Jon Skeet May 18 '13 at 14:53
  • @JonSkeet: But what is the difference between `catch`, `catch (Exception)` and `catch (Exception ex)`? The first one does nothing than catching everything, the second only the type, and the third also the details? What should you catch other than an exception? – testing Jul 19 '17 at 12:57
  • 3
    @testing: You'd normally catch a *specific* exception type. As per the answer, before .NET 2.0 there were weird situations where `catch(Exception) { }` might not catch everything, but `catch { }` would, IIRC. But fortunately those days are long gone. – Jon Skeet Jul 19 '17 at 13:00
10

I think they are the same. But the second case raised a compiler warning because you declare an exception you didn't use. I rather like the first one because you say explicitly that you don't use the exception. There is also a third one

catch (Exception)
{
    //do something
}

if you want to specify the type of exception but doesn't care about the exception itself.

Iesvs
  • 125
  • 2
6

Generally you should catch specific errors first.

But if you go for catching a general Exception like you do I'd say use the second case:

catch (Exception ex)
{
     MessageBox.Show("Error.");
     //we never use ex, so is it better to use catch without arguments?
}

this can help you with debbuging since the variable contains the stack trace, exception message...etc. Which you can use for logging the error or something that will help you preventing it.

Be very carefull using this approach, though:

MessageBox.Show("Error.");

Not keeping track of your errors somewhere(like a log file) can cause a really big mess.

TheBoyan
  • 6,802
  • 3
  • 45
  • 61
  • The exception data is reachable anyway. If you step into an exception without a variable, a symbol will show up that will show you exception data. – GeirGrusom Nov 04 '11 at 13:24
  • @GeirGrusom - yes, but you can't use that info for logging in a file or something can we? – TheBoyan Nov 04 '11 at 13:25
  • @GeirGrusom sure, you can see the exception when you're debugging, but you don't have a reference to it to use in logging or displaying the appropriate message to the user. – DOK Nov 04 '11 at 13:28
3

In your second example you can reference exception data, like the stack trace, source, etc. It also gives a general message that is sometimes helpful. It tells you WHY you suffered an exception which is important when debugging.

Jeff LaFay
  • 12,882
  • 13
  • 71
  • 101
  • 1
    I think you missed the point, the first one catches all exceptions, the second one catches .NET exceptions – Kieren Johnstone Nov 04 '11 at 13:22
  • Actually all they asked was what the difference is between two catch examples and that's the difference. Either you reference the exception or you don't. And so you know, both examples catch all .Net exceptions. Any exception you catch will be a ".Net exception" because this is C#. It's also important to note that all exceptions have the Exception class in their inheritance tree because an exception class must inherit it either directly or indirectly by inheriting from another class that has inherited the Exception class. – Jeff LaFay Nov 04 '11 at 13:39
  • you are mistaken, some exceptions do not inherit from Exception. Ones created by user code, or C# code do, but some others do not – Kieren Johnstone Nov 04 '11 at 14:33
  • I really hate to get sucked into your trolling but I've understood it that in order to throw an exception you have to inherit from Exception. So I tried out what you said, created a class and then tried to throw a new instance of it. It resulted in an exception with this message "The type caught or thrown must be derived from System.Exception". And what in the world do you mean by "C# code do, but some others do not". Considering your reputation, I'm really shocked that you didn't know trivial exception handling/behavior. – Jeff LaFay Nov 04 '11 at 14:56
  • 2
    jlafay - Again, you are mistaken. Some unmanaged code (i.e. not C# and not .NET) throw exceptions that are not derived from Exception. Why would you assume I'm trolling? – Kieren Johnstone Nov 04 '11 at 17:32
  • Do you have examples? I don't work with a lot of unmanaged code and if .Net can handle exceptions that aren't .Net exceptions I'd be interested in knowing. Or maybe if you have a link that I could read. – Jeff LaFay Nov 04 '11 at 17:50
  • http://msdn.microsoft.com/en-us/library/ms229005.aspx- "Do not handle non-CLS-compliant exceptions (exceptions that do not derive from System.Exception) using a parameterless catch block. Languages that support exceptions that are not derived from Exception are free to handle these non-CLS compliant exceptions." - Looks like it's changed in .NET 2.0 though. – Kieren Johnstone Nov 04 '11 at 18:48
  • Ok that says non-CLS compliant and unmanaged exceptions (if those exist) would be non-CLS compliant. Which exceptions can you catch from unmanaged assemblies that aren't wrapped by an exception that inherits from System.Exception? – Jeff LaFay Nov 04 '11 at 19:14
0

Some exception can not be catch(Exception) catched.

Below excecption in mono on linux, should catch without parameter.

Otherwise runtime will ignore catch(Exception) statment.

System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.

If you encounter the problem like that, try remove parameter of catch statement, log the context vars to find out error cause.

P.S. I don't know how on windows, the program run in windows is normal.

IlPADlI
  • 1,943
  • 18
  • 22