Functions – Exceptions Instead Of Error Codes

Maybe at some point you’ve written a function that had several possible results, and depending on the result, you had to do different things or show different error messages. One thing you might be tempted to do is have the function return a number representing the result code, or maybe the function returned an enumeration. While this may be a valid thing to do in certain cases, you should try to avoid it.

Why shouldn’t you use Error Codes?

It violates Command Query Separation

If you read the post about Command Query Separation, then you can see that this approach violates that principle.

It makes you write more code

If you call a function that returns error codes, then it is safe to assume that you will want to act according to the error code received. Usually this happens via a switch statement.

// things that happen before calling the function
int code = MyFunctionThatReturnsErrorCodes();
switch(code){
  case 0:
    //if 0 means success then we continue our function here
    break;
  case 1:
    //handle this error
    break;
  ...
  case 10:
    //handle this error
    break;
}
// things that happen after calling the function

This means that your function will have to handle every single possible error. If there are a lot of things that can go wrong, then your function will be large because of all the error handling code.

It makes modification difficult

What happens when your function has a new possible error that can happen? Not only will you have to change the function (and the enumeration if you are using one for the possible errors), you will also have to change all the code that calls that function and handle the new error code. That means adding an extra case to all the switch statements in the previous example. If the code that calls the functions is in a different assembly, then those assemblies will have to be recompiled as well (and that can make you a lot of new enemies very quickly!)

Error handling is one thing

Many people would argue that error handling is one thing. That means that a function that handles it’s errors is doing more than one thing. It would be better to have a separate function that handles the possible errors that could happen,

Use exceptions instead

A better approach would be to have your Command functions not return an error code, but make them throw an exception when an error happens. When you call the function, assume that everything will work correctly.  and use a try/catch statement to handle any errors outside of the logical flow of the function itself.

try{
  // things that happen before calling the function
  MyFunctionThatThrowsExceptions();
  // things that happen after calling the function
}
catch (Exception e)
{
  // handle possible errors here, preferably in a separate function
}

The code in the previous example is easier to read. You assume that your functions will work without errors and if an error happens, there is a separate piece of code that will handle that error. We are also respecting Command Query Separation, while having functions that do one thing.

Leave a Reply