Exceptions 1: Basics

This is the first of two things requested by Jesper.  Please visit his blog for wisdom about testing, business strategy and things like that. I’m not always available for weddings and bar mitzvahs, but if anyone else has requests or suggestions for the blog, please let me know via the Contact page.

This started off as a single article, but it soon became obvious that there would need to be a series of articles:

  1. Basics
  2. Types and filtering
  3. Where to put catch blocks and handle exceptions
  4. Finishing up
Someone shooting a flare pistol
An exception is like a signal flare for your code
Image credit

Introduction

Exceptions are a way of reporting and handling errors in your code.  There are other ways of doing this, which I’ll go into the last article, but exceptions are a common approach across many languages.  At the highest level, learning about exceptions has an easier bit and a harder bit.

The easier bit is learning what they are and how they work, which are just facts.  The harder bit is learning when to use them rather than an alternative, because this is more in the area of judgement, i.e. “it depends”.

I’ll try to go into both areas in this series.  It will be in the context of C#, but I hope that enough is generally useful to other languages.

Basics

There are two main kinds of thing you’ll see in code to do with exceptions:

  1. The exceptions themselves
  2. Special-purpose code that creates and processes exceptions

An exception is an object with a type (more on that in the next article), that’s created with new as objects generally are.  Once you create it, it just sits there not doing anything special.

To get the special behaviour you need to use the commands related to exceptions: throw, try, catch, and finally.  I’ll briefly explain them here, but go into more detail below:

  • Throw – sets the exception on its way, like return does to the results of a method
  • Catch – marks an area of code that potentially deals with an exception
  • Try – marks an area of code as being associated with a particular catch
  • Finally – marks an area of code as always being executed, regardless of whether exceptions happen or not (e.g. to do non-exception tidying up after the code that gave rise to the exception).

It’s important to realise that exceptions are an additional way of passing stuff out of a method, on top of the normal results it can return.  However, they don’t show up in the method’s signature.  For instance:

int divide(int numerator, int denominator)
{
   if (denominator == 0)
   {
      throw new Exception(“Can’t divide by zero”);
   }

   return numerator / denominator;
}

This method will return either an integer or an exception, but the method signature only mentions the return type of int.  Line 5 creates a new exception, passing it an error message, and immediately throws it.  (This is the most common pattern, in my experience.)

The simplest way of calling a method like this (assuming you will be dealing with exceptions) is something like this:

void someOtherMethod(int numberA, int numberB)
{
   try
   {
      int result = divide(numberA, numberB);
      Console.WriteLine($“The answer is {result}“);
   }
   catch (Exception e)
   {
      Console.WriteLine(“There was an error: ” + e.Message);
   }
}

The try on line 3 marks the region of code on line 4 to 7 as the region to which the catch block (the exception handler) starting immediately after it should apply.

Note that I wrote “assuming you will be dealing with exceptions” – this is important.  You don’t have to put a try/catch around calls to code that could generate exceptions.  I will go into catch blocks in more detail in the next article.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s