Throw Often, Catch Rarely


In Software Engineer, we get to hear the proverb a lot: “Throw Often, Catch Rarely“. This is a very good programming practice that should be added to your coding guidance.

Throw Often

Throwing exceptions is a good sign of spotting errors early. If you are sure that something is wrong, throw an exception, simple as that. For example, if the value of a parameter to a function does not make sense, throw it instead of continue the function execution with uncertain behavior.

1
2
3
4
5
6
7
int iSqrt(int n) {
   if (n < 0) {
       throw "Negative Square Roots";
   }
   // for simplicity
   return (int)sqrt(n);
}
int iSqrt(int n) {
   if (n < 0) {
       throw "Negative Square Roots";
   }
   // for simplicity
   return (int)sqrt(n);
}

If a file needed does not exist, make it be aware. If you are going to delete a file, but that file is being in used, throw an exception instead of ignoring it or killing whatever application that uses that file (if you can).

The essence of this idiom is to let us (human) know instead of ignoring the problem or dealing with it base on some assumption at that point. Because, it might come back and bite you with a much bigger and worse trouble (so-called butterfly effect).

Exceptions have to be specific. For example, if a file-is-not-found, then throw a FileNotFoundException, if the parameter is invalid, throw InvalidArgumentException. Specific exceptions help to understand the codebase and you can add customize exception handler easily in the upstream.

Catch Rarely

So, let’s say you throw hundreds of exceptions in your codebase, when to handle them? Obviously, if you just leave them, the exceptions will not go away. They will pop up to the upstream if not caught and handled, so what the user might see is an ugly exception dialog, like this:

file-not-found-exceptions Throw Often, Catch Rarely exception handling software design software development

file-not-found-exceptions

Only Catch When You Know How to Handle

The golden rule here is:

Only catch exceptions that you know how to handle! Click To Tweet

Otherwise, let the exceptions pop upstream. However, you might want to do some logging with more detailed information and re-throw it.

1
2
3
4
5
6
try {
 
} catch (BadExceptionButIDontKnowHowToHandle ex) {
   Logging(MoreDetailedInformationInThisMethod);
   throw; // so upstream may handle it correctly.
}
try {

} catch (BadExceptionButIDontKnowHowToHandle ex) {
   Logging(MoreDetailedInformationInThisMethod);
   throw; // so upstream may handle it correctly.
}

The throw without parameter preserves the stack trace that is important to identify the root cause of a problem. If you do throw ex that will destroy the stack trace.

Catch More Specific Exceptions First

You might want to deal with the more-specific exceptions first and then less specific exceptions. For example:

1
2
3
4
5
6
7
8
9
10
try {
 
} catch (IOAccessPermission ex) {
 
} catch (IOException ex) {
 
} catch (Exception ex) {
  Log(ex); // add logging;
  throws;
}
try {

} catch (IOAccessPermission ex) {

} catch (IOException ex) {

} catch (Exception ex) {
  Log(ex); // add logging;
  throws;
}

In this case, IOAcessPermission inherits from IOException which inherits the general Exception class. Inside catch block, sometimes you might want to filter out unwanted situations, deal with the ones you are familiar with, and re-throw the exception, like this:

1
2
3
4
5
6
7
8
try {
 
} catch (SomeException ex) {
  if (ex.ErrorCode == ERROR_SPECIAL_CASE) {
      CleanUp();
      throw;
  }
} 
try {

} catch (SomeException ex) {
  if (ex.ErrorCode == ERROR_SPECIAL_CASE) {
      CleanUp();
      throw;
  }
} 

Don’t Suppress Errors

If used incorrectly, catching exceptions can be considered as suppressing errors. It is almost true to avoid catching general exceptions.

1
2
3
4
5
try {
  some_function();
} catch (Exception ex) {
  // fixing the annoying bug showing exceptions.
}
try {
  some_function();
} catch (Exception ex) {
  // fixing the annoying bug showing exceptions.
}

Suppressing errors may likely to cause a bigger trouble later. And sometimes it is just wrong: Considering a customer spent days and nights working on a design project, and the prototype in fact is faulty because the elementary calculations are incorrect, as suppressed by the exceptions-catching.

Exceptions to Avoid

Some exceptions should not be thrown in the first case. For example, parsing a string to number. Use int.TryParse instead of int.Parse, which throws exception when string cannot be converted into a integer.

Accessing array given an index that is not valid (out of bounds) normally means that your code is buggy, which should be investigated.

Object reference not set to an instance of an object: This can be avoided and should not be handled as exception. This error should be corrected even before you hit compile.

object-reference-no-stet-to-an-instance-of-an-object Throw Often, Catch Rarely exception handling software design software development

object-reference-not-set-to-an-instance-of-an-object

Out of Memory exception: Try to optimise the memory usage. Do you really need to allocate that much? And also do not try to clean up (save) the array because at that point, it is likely the heap is corrupted. It is better to kill the process and let the OS clean up the mess.

1
2
3
4
5
6
double *a;
try {
  a = new double[TO_MANY_TO_COUNT];
} catch (OutOfMemory ex) {
  delete []a; // this will make it even worse.
}
double *a;
try {
  a = new double[TO_MANY_TO_COUNT];
} catch (OutOfMemory ex) {
  delete []a; // this will make it even worse.
}

Exceptions to Catch

There are things that could go wrong. File I/O is one of them: hard disk out of space, hard disk corrupted, not enough file access permissions etc. If you are coding online gaming, dealing with users disconnected should be in the checklist.

In the old days (DOS), we used to do similar things by checking the error code after each function call. The modern programming languages provide exception handling, which just makes the code easier, and more elegant to write. So start using exception-handling!

catch-general-exception Throw Often, Catch Rarely exception handling software design software development

catch-general-exception

Throw Often and Catch Rarely! Click To Tweet

–EOF (The Ultimate Computing & Technology Blog) —

GD Star Rating
loading...
1076 words
Last Post: Useful Tools for Beginners of JavaScript
Next Post: How to Read and Write a Binary File At the Same Time in C#?

The Permanent URL is: Throw Often, Catch Rarely

Leave a Reply