When to throw exceptions

I’ve written several posts about exceptions. For instance when you should catch them or how you should design them. In this post I’ll discuss when you should throw exceptions.

Exceptions are thrown when something exceptional have happended. But what does that mean? In fact it’s really simple. Let’s look at an example interface:

interface IUserRepository
{
	void Save(User user);
}

You should throw an exception every time that method fails to save the user into the data source. The failure reason do really not matter. All of these reasons are valid:

  • The user object do not contain all mandatory information
  • The user object is null
  • The data source is off line
  • The data source rejected the save.

Why? Because the method is named Save and returns void. That is, the contract of the method indicates that a save should in most cases be successful. Hence something exceptional have happened if the user is not saved into the data source.

But couldn’t you have written something like this instead:

interface IUserRepository
{
	bool Save(User user);
}

Yes, sure. That method would return false instead of throwing exceptions. But the method contract indicates that the method can fail as many times that it can succeed. You really do not mean that, do you?

but.. but… The Remove method usually returns a bool.

interface IUserRepository
{
	bool Remove(User user);
}

Yes. It do. The reason to that is that it says that it’s OK to call Remove even if the user do not exist. imho it’s a vague contract. It’s not clear if the method means that the removal is expected to fail or if the method allows you to remove non-existing items. I would have used void as return value instead.

Myth: Exceptions are expensive

First of all: Exceptions that are not thrown are not expensive.

And if you start to think about it, exceptions are actually a lot cheaper than using return values. Exceptions forces you to take action, no action means that your application crashes. The exceptions also include the exact location of the error. Return values only work if you check and handle all of them. I would like to see any reasonable sized application which uses return values where all of them are handled.

The point is that it’s a lot more tedious task to find and fix bugs in applications that uses return values instead of exceptions since you have to use details logs or reproduce errors to be able to locate and fix them. The amount of time spend to locate and correct errors probably costs a lot more money than buying new hardware to make up for the exception performance penalty.

Summary

Throw exceptions if the method contract is violated.