Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / programming / exceptions

What are Exceptions?

5.00/5 (2 votes)
4 Apr 2013LGPL34 min read 11.7K  
This post will discuss what exceptions are.

This blog has been quiet for a while. I am currently writing a book about localization. Me and my partner are also getting close to the release of our new startup. One of its features is to automatically catch unhandled exceptions and send them to a webservice for analytics. But to take full advantage of that, you’ll have to use a set of exception handling best practices. I’m therefore going to write a set of exception articles. The series will end with the release of our service.

What is So Exceptional with Exceptions?

Meet Bob:

bob

He got more money than he can handle. Hence every time he shops, he just swipes that bling bling card and pays.

Meet Sam:

poor-man-begger

He is not as fortunate and every dollar counts. That means that he doesn’t just swipe his credit card and expect it to work. He usually stops by at the ATM before to check the balance.

What I’m saying is that both of them got the use case “Pay items with a credit card”. But as Bob doesn’t expect the card to be empty, he just swipes that bling bling card without doing any prior checks. Sam, on the other hand, expects the payment to fail. He’ll therefore makes sure that there is enough money on the card before swiping it.

Now, imagine that someone has hacked Bobs card so it’s empty. He’ll go into the shop with that big fat grin and shop like a madman as he usually do. But this time, he gets a surprise: There is no money in the account. He understands what’s wrong, but not why. Hence, there is really nothing that he can do about it. He’ll have to go home and try to understand what happened and also try to prevent it from happening in the future.

And that’s what an exception is.

Code Example

If you have an XML file which is shipped with your product, for instance a product list, you expect it to exist. If it doesn’t, there is not much you can do about it. Hence something exceptional has happened.

If you on the other hand have an XML file which contains a cache of the most recently used products, you’ll expect that file to not exist the first time. If it doesn’t, you simply create it and add the product that the user is currently working on.

What I’m saying is that what’s exceptional depends on the use case. In one case, it’s vital that the file exists, in another case, you can continue by just creating the file.

Exceptional cases are when you can’t rescue the situation to allow the application to continue as expected.

If we translate both cases into code, the first one will look something like this:

C#
public IEnumerable<Product> GetProducts()
{
    using (var stream = File.Read(Path.Combine
    (Environment.CurrentDirectory, "products.xml")))
	{
		var serializer = new XmlSerializer();
		return (IEnumerable<Product>)serializer.Deserialize(stream);
	}
}

In the above example, you do expect the file to exist. So you should not try to handle any exceptions in it (as there is really no way to recreate the product list).

The other example on the other hand expects the file to not exist. So we do check if the file exists:

C#
public IEnumerable<Product> GetCachedProducts()
{
	var fullPath = Path.Combine(Environment.CurrentDirectory, "ProductCache.xml");
	if (!File.Exists(fullPath))
		return new Product[0];
		
	using (var stream = File.Read(fullPath))
	{
		var serializer = new XmlSerializer();
		return (IEnumerable<Product>)serializer.Deserialize(stream);
	}
}

When to Catch Exceptions

So when should you catch exceptions?

When you can make the method return, what is expected of it.

Let’s use the above examples again:

C#
IEnumerable<Product> GetProducts()

This method says that it should always return a list of products. If you can do that by catching an exception in it, go ahead and do it. If you can’t, you should not catch exceptions in it.

C#
IEnumerable<Product> GetCachedProducts()

This method is a bit trickier. We could catch FileNotFoundException in it and use that to detect if the cache file is missing. That, however, communicates that we expected that the file should exist, but that we can rescue the situation by handling the exception. That is not true. We do expect the file to not exist.

Summary

Exceptional cases is usually something that you can’t foresee. It can be a logical error made by you (read: bug) or something out of your control (like OS/Network/Disk errors). That means that you can’t in most cases handle those errors even if you try by catching them. Or even worse: You catch them, fail to handle them, and have by doing so hidden a bug which will be much harder to find and solve. Simply don’t do anything with exceptions that you can’t handle.

If you want to catch exceptions to log them, do that in your top layer (like WCF or ASP.NET MVC). Your code will get a lot less cluttered.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)