Tuesday, July 1, 2008

Why you shouldn't just wrap simple code in a try-catch

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/why_you_shouldnt_just_wrap_simple_code_in_a_trycatch.htm]

Structured programming languages, like C#, provide a try-catch ability to wrap an entire block of code, and catch if anything goes wrong. This can massively simplify error checking, especially when calling external components. However, like any good thing, it can also be abused. During interviews, or rushing out code, many developers resort to using try-catch as a quick way of doing error checking, but there's a catch (excuse the pun). For example, consider this trivial method to sum up an array of integers:

 

    public static int GetSum(int[] aInt)
    {
      int intSum = 0;
      foreach (int i in aInt)
      {
          intSum += i;
      }
      return intSum;
    }

 

You can crash this code, such as by passing in null for the int array.  To blindly wrap a simple method with try catch, just to catch normal logic errors like null variables or indexOutOfRange, has problems.

  • For performance, Try-catch is enormously expensive compared to an if-then check. It could be hundreds of times slower. So it's bad design to use a try-catch for something trivial when an in-then will do just file, like checking if a variable is null.

  • What will you do in the catch statement? Some devs may say "I'll log my exception info here" - but what info is that... that the developer didn't bother to do basic error checking?

  • It makes the usability worse. Perhaps instead of re-throwing an exception, or logging and going to the global error page, the method could have used an if-then to return a sentinel value instead. For example, perhaps a string manipulation method could just return the original value (or null) if the input parameters were invalid.

  • It loses context. Say your code catches a null exception - that thrown exception doesn't tell you what variable was null. You've lost context and information with which to fix the code. Using an in-then would have given you full access to all the local variables and their context.

  • It makes all exceptions equal - a null or indexOutOfRange exception (things that are easy to catch with if-thens) are put on the same level as a critical outOfMemory error - i.e. both trigger the catch block. This in turn can distract the maintenance team, who gets swamped with tons of exceptions, most of them preventable.

  • Perhaps worst of all, it implies that the developer isn't thinking about how their method can fail. Rather than understanding the code and what it does, they just wrap it all in a try-catch, and move on. This means they could have not coded for valid use cases.

Try-catch has obvious benefits, but it has limitations and consequences too. There are times when it's much more beneficial to explicitly catch the error conditions with an if-then instead.

No comments:

Post a Comment