16

I want to know if I can safely write catch() only to catch all System.Exception types. Or do I've to stick to catch(Exception) to accomplish this. I know for other exception types (e.g. InvalidCastException), I have to specify the type as catch(InvalidCastException). In other words, I'm asking if the following code samples are the same.

This ...

try
{
    //do something
}
catch(Exception)
{
    //handle exception
}

this ...

try
{
    //do something
}
catch() //Causes compile time error "A class type expected"
{
    //handle exception
}

and this ...

try
{
    //do something
}
catch
{
    //handle exception
}

update: There was an error in my question. catch() is not allowed in c#.

CleanCoder
  • 807
  • 1
  • 9
  • 19
  • 1
    Yes they all are same , However it is not same for c#.net . – Shankar Narayana Damodaran Jan 17 '12 at 19:58
  • 1
    Yes, all of those are the same. Any way you write it, it's a bad idea. You should only catch those exceptions you are prepared to handle. Unconditionally catching all exceptions is not what I would call "clean code." – Jim Mischel Jan 17 '12 at 20:00
  • 1
    What do you plan to do inside of the catch block. What do you consider "handling" the exception? None of your three examples have access to the exception itself, so it's hard to think how you could usefully "handle" it. – John Saunders Jan 17 '12 at 20:03
  • I started working on a project someone else wrote. And I'm getting about 50 compile time warnings with description "The variable 'ex' is declared but never used". And the line of code has `catch(Exception ex)`. I was going to just remove the declaration and simply put `catch` to resolve the compiler warning. – CleanCoder Jan 17 '12 at 20:11
  • @sh4nx0r Can you explain how they're different in C#.net? I'm using C# for my project. – CleanCoder Jan 17 '12 at 20:13
  • 1
    in C#.net , you have to exclusively specify `catch(Exception)` or `catch(NullReferenceException)` [If you know the exception] . In C#.net. You can't let the catch block empty like this catch() , Intellisense will show errors. – Shankar Narayana Damodaran Jan 17 '12 at 20:24
  • 1
    @CleanCoder: depending on your project, you should probably not "handle" exceptions at all. – John Saunders Jan 17 '12 at 20:24
  • @sh4nx0r Thanks for the correction on catch(), I've updated the question to reflect that it's not allowed. – CleanCoder Jan 17 '12 at 20:37
  • Yes you can. http://msdn.microsoft.com/en-us/library/0yd65esw.aspx – Marius Jan 17 '12 at 19:58
  • Adding to Jim Mischel's comment, there are exceptions to the rule of not catching all exceptions for CleanCode. There are often places where you simply are not allowed to propagate exceptions to the caller because it won't work. This is sometimes the case with events or call-backs that come with native code. Excel add-ins are one examples. Other extensions also have this issue. Another case inter-process communication when full-exception propagation is disabled by default, such as with WCF. You *have* to catch *all* exceptions in those cases. You then have to figure out what to do. – zumalifeguard Feb 01 '17 at 18:14

5 Answers5

15

In a perfect world, you shouldn't use catch(Exception) nor catch (alone) at all, because you should never catch the generic Exception exception. You always should catch more specific exceptions (for instance InvalidOperationException...etc.).

In a real world, both catch(Exception) and catch (alone) are equivalent. I recommend using catch(Exception ex) when you plan to reuse the exception variable only, and catch (alone) in other cases. Just a matter of style for the second use case, but if personally find it more simple.

What's really important (even if it's out of the scope of your question) is that you never write the following piece of code:

try
{
}
catch (SpecificException ex)
{
    throw ex;
}

This would reset the stack trace to the point of the throw. In the other hand:

try
{
}
catch (SpecificException)
{
    throw;
}

maintain the original stack trace.

ken2k
  • 48,145
  • 10
  • 116
  • 176
6

Both constructs (catch () being a syntax error, as sh4nx0r rightfully pointed out) behave the same in C#. The fact that both are allowed is probably something the language inherited from C++ syntax.

Others languages, including C++/CLI, can throw objects that do not derive from System.Exception. In these languages, catch will handle those non-CLS exceptions, but catch (Exception) won't.

Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479
  • see comment above by sh4nx0r, the construct catch() is not allowed in C#, it throws compile error "A class type expected". – CleanCoder Jan 17 '12 at 20:38
  • @CleanCoder, you're right, I was definitely thinking too much about the other languages. Answer updated accordingly, thanks for the heads-up :) – Frédéric Hamidi Jan 17 '12 at 20:45
2

catch(Exception ex) can handle all exceptions which are derived from System.Exception class, however if the exception thrown is not derived from System.Exception then it will not be handled by catch(Exception ex).

Prior to .NET 3.0 exceptions thrown by unsafe code (i.e. code not targeting CLR) were handled by catch{}. After .NET Framework 3.0 all types of exception can be handled by System.Exception class. catch{} is now obsolete .

Nameless One
  • 1,615
  • 2
  • 23
  • 39
Yogesh
  • 29
  • 2
1

Take a look at this link: http://msdn.microsoft.com/en-gb/library/0yd65esw.aspx

I think it will be ok, have or not but you can let argument in statement catch to get exactly the exception that you want and handle them rightly.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Raphaël VO
  • 2,413
  • 4
  • 19
  • 32
-1

If the fact that an exception occurs implies that you need to run a piece of code, but you wouldn't do anything with the exception except rethrow it if you caught it, the preferred approach is probably not to catch the exception but instead do something like:

  bool ok=false;
  try
  {
    ... do stuff -- see note below about 'return'
    ok = true;
  }
  finally
  {
    if (!ok)
    {
      ... cleanup code here
    }
  }

The one weakness with this pattern is that one must manually add an ok = true; before any return statement that occurs within the try block (and ensure that there's no way an exception (other than perhaps ThreadAbortException) can occur between the ok = true; and the return). Otherwise, if one isn't going to do anything with an exception, one shouldn't catch it.

supercat
  • 77,689
  • 9
  • 166
  • 211
  • -1, Catch() is actually very useful. If I am updating 10 records and one of them throws an exception of invalid date. If I do not use catch, none of the records following that exception will be updated. If I use catch I can simply recognize that error show it to the user while update the rest of the records. – TheTechGuy Mar 01 '12 at 20:50
  • And what do you do with the exception? Either discard it or store it for later use, I would expect. I was suggesting my code as an alternative to the pattern where one would do an unconditional parameterless rethrow within a `catch` block. It is not an alternative for cases where the catch block isn't going to rethrow. – supercat Mar 01 '12 at 21:00
  • No, I think you are wrong. You are saying, you simply rethrow the exception after it is caught? That is wrong. You catch the exception, show it to the user in a nice wand the rest of the program executes fine. Why would I store my exception? – TheTechGuy Mar 01 '12 at 21:14
  • @Thecrocodilehunter: My point was that the "try/finally" code I gave was an improved alternative for a scenario where one would *otherwise* use `catch(Exception ex) {...do something...; throw;}`, which is a pattern I have often seen used. For the scenario you describe, one wouldn't use the latter pattern, and thus my former pattern shouldn't be considered a substitute. – supercat Mar 01 '12 at 21:30