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.

The art of creating exceptions

This will be my final piece on exception handling. It’s been fun, but the show must go on, right? Got any suggestion on what I should rant about in this blog? Leave a comment.

Please take a moment and think about WHY you throw exceptions.

You done? Have you come up with a reason? You are probably thinking: “That b!@tch is a total moron. I throw exceptions to know that something exceptional have happened!”. If that is the case, please stop reading here. (The first part of the thought is totally fine by me, I can be a total moron.)

.
.
.
.
.
.

I SAID STOP READING!!!!

.
.
.
.
.
.
.

Really!

.
.
.
.
.
.
.
.
.

No? Well. Ok then. Want to be an exception master? Got some ninja skills? Have you bought a jump suit? I have actually created a diploma (yes, It’s true) that I will email to anyone who leave a comment that says: “I throw exceptions to be able to try to prevent them in the future”. Because that’s what you should really try to do. Sure, some exceptions that are thrown CAN’T be prevented. But a lot of them can.

Let’s take FileNotFoundException as an example. It can in MOST cases be prevented, if you are not a lazy SOB, by checking if the file exists before trying to open it. The exception can STILL be thrown if the file is deleted between the check and and you opening it. Life is harsh, isn’t it.

The problem is that if you do not provide any contextual information you will have a hard trying to prevent it in the future.

Instead of just writing

  throw new FileNotFoundException("Ohhh, the file was missing! *buhu*");

do write

  throw new FileNotFoundException(string.Format("Failed to find '{0}'.", amazingFileName));

Even better would have been if you could add some more context and add the filename as a parameter:

  throw new FileNotFoundException(string.Format("User photo for user #{0} was not found", userId)) { Filename = amazingFilename };

That gives a lot more information to work with, don’t you think? When designing exceptions you should ask yourself “What kind of context information can I provide in this exception to make it easier to prevent it?”. Regarding a file it’s quite obvious. Hence I would design the exception like this:

  public class FileNotFoundException : IOException
  {
      public FileNotFoundException(string message, string fileName)
	     : base(message)
	   {
			Filename = fileName;
	   }

       // *ALWAYS* include a constructor which takes a inner exception.
	   //
	   // I WILL HUNT YOU DOWN AND GIVE YOU SOME SPANKING IF YOU DON'T!
       public FileNotFoundException(string message, string fileName, Exception inner)
		: base(message, inner)
	   {
	   }

      public string Filename { get; private set; }
  }

Let’s look at another example.

I’ve talked about a DataSourceException in previous posts. It could be used to report problems in the data layer (regardless of the type of data source). The first thing that comes into my mind is that we have a target and some parameters. When using a web service, the target is the URI and the parameters are anything posted. Likewise, for SQL the target is a SQL query and the parameters is the parameters used in the SQL query. Doing it like this creates a potential security risk. Do NOT expose exception details for the end users, never ever.

  public class DataSourceException : Exception
  {
	public DataSourceException(string message, string target, Dictionary<string, object> parameters)
	     : base(message)
	{
			Filename = fileName;
	}

       public FileNotFoundException(string message, Exception inner, string target, Dictionary<string, object> parameters)
		: base(message, inner)
	{
	}

	public string Target { get; private set; }
	public Dictionary<string, object> Parameters { get; private set; }

  }

How it can be used for a webservice request:

	try
	{
		var user = myWebSvc.GetUser(userId);
		if (user == null)
		  throw new InvalidOperationException(string.Format("Failed to find user #{0}", userId)); //kilroy was here
	}
	catch (WebException err)
	{
	    throw new DataSourceException(string.Format("Failed to download user.", userId), myWebSvc.Uri, userId);
	}

Or for a database:

	string errMsg = "Failed to update user";
    ExecuteCommand(cmd => {
		cmd.CommandText = "UPDATE user SET name=@name WHERE id=@id";
		cmd.AddParameter("name", name);
		cmd.AddParameter("id", userId);
	}, errMsg);

Where did all code go? It’s a small method looking like this:

	public void ExecuteCommand(Action<IDbCommand> action, string errMsg)
	{
		// CreateConnection() uses DbProviderFactory and
		// throws DataSourceException if connection fails
		using (var connection = CreateConnection())
		{
			var cmd = connection.CreateCommand();
			try
			{
				action(cmd);
				cmd.ExecuteNoQuery();
			}
			catch (DbException err) //notice that I only handle DbException?
			{
				// WTF is this? Check next code snippet.
				// note that I *return* an exception from the extension method (instead of throwing it)
				throw cmd.ToException(errMsg, err);
			}
			finally
			{
				cmd.Dispose();
			}
		}
	}

I used a small extension method:

    public static class DataExtensions
	{
		public static Exception ToException(this IDbCommand command, string errMsg, Exception inner)
		{
			var parameters = new Dictionary<string, object>();
			foreach (var p in command.Parameters)
				parameters.Add(p.ParameterName, p.Value);
			throw new DataSourceException(errMsg, inner, command.CommandText, parameters);
		}
	}

Summary

You should be fine if you stop to think “I throw exceptions to inform that something exceptional happens” and instead start thinking “I throw exception to help try to prevent the exceptional cases from happening in the future”. Having that mindset helps you create much more detailed exception classes (and hopefully also provide that information).

Each time you are about to throw an exception ask yourself: What information can I provide in this method to make it easy to find out why the exception was thrown? It might take a couple of minutes longer, but how long does it take to debug your application if you do NOT get that information? Usually a lot longer.

Action points for you:

  1. Create exception classes containing as much context information as possible
  2. Always create a constructor that takes an inner exception
  3. Throw exceptions to help prevent them in the future
  4. Try to include as much context information as possible

Update

Hold the presses. I got so carried away by my bright ideas for this article that I got a bit blinded by the brightness. The most important reason to a throw exception is to be able to handle it. That’s why you throw DataSourceException and not Exception. The more specific, the merrier.

Common mistakes when working with exceptions

There are a few mistakes that’s really common when it comes to exception handling and I though that I should write a small entry about them.

Rethrowing and destroying the stacktrace

This is a evil one. Because it’s really easy to use it and the compiler do not complain about it (it should be easy to spot by the compiler). The code also looks correct if you don’t know what it really does.

What am I talking about?

    try 
    {
        FutileAttemptToResist();
    }
    catch (BorgException err)
    {
         _myDearLog.Error("I'm in da cube! Ohh no!", err);
        throw err;
    }

Looks about right? The problem is the throw err; part. It will wipe the stack trace and create a new one from your catch block. You’ll never know where the exception originated from. Just use throw;

Using policies for exception handling

I’ve started to write several pieces about why you should not use policies (for instance Exception Handling Block in Enterprise library) but I never got really satisfied with it.

The problem with the block is that the examples is still not very good and really tricks you into bad practices.

Anyway, introducing policies can be good if you are following my guidelines in the post “Do NOT catch that exception!”. The problem though is that it’s easy to start adding try/catch/policy everywhere and hence producing unreadable code that is logging the exception multiple times again.

Just handle those exceptions that you can handle. No need for a policy.

Not including original exception when wrapping

Another common mistake is to not include the original exception when throwing another one. By failing to do so, you are also failing to give information about where the error really happened.

    try
    {
        GreaseTinMan();
    }
    catch (InvalidOperationException err)
    {
        throw new TooScaredLion("The Lion was not in the m00d", err); //<---- original exception is included, hooray!
    }

Not providing context information

This one is actually a golden rule at Microsoft. They really love to give us developers a challenge when something fails. They have built a superior framework with .Net and they need to put us developers back to earth sometimes. Hence the crappy exception descriptions.

This is what I’m talking about:

    try
    {
       socket.Connect("somethingawful.com", 80);
    }
    catch (SocketException err)
    {
        throw new InvalidOperationException("Socket failed", err);  //I LOVE InvalidOperationException. Read my previous post.
    }

What’s wrong? The exception message is just stating the obvious. We already know that the connect fails. But we do not know what it tried to connect to. Always provide contextual information. NHibernate is the glorious king when it comes to developer friendly exceptions. Examine it’s source code and learn something.

what you really should do is something like this:

    void IncreaseStatusForUser(int userId, int newStatus)
    {
        try
        {
             var user  = _repository.Get(userId);
             if (user == null)
                 throw new UpdateException(string.Format("Failed to find user #{0} when trying to increase status to {1}", userId, newStatus));
       
             user.Status = newStatus;
             _repository.Save(user);
        }
       catch (DataSourceException err)
       {
           var errMsg = string.Format("Failed to find modify user #{0} when trying to increase status to {1}", userId, newStatus);
            throw new UpdateException(errMsg, err);
       }

I always try to include as much information as possible in my exceptions. One could discuss if that sensitive information should not be included in exceptions. But I say YES! It’s really up to code that EXPOSES the exception (for instance a logger or a message box) to hide sensitive information. For instance, only log exceptions in a log that the correct people have access to. Exceptions should be dealt with ASAP anyway.

I would never expose a exception to a end user. What use do they have of the exception information? You got a widely used application and need to get exception information? Encrypt it and upload it to your server (with permission from your user of course).

InvalidOperationException: “Exception” in disguise? Or just the new ApplicationException?

Microsoft added ApplicationException with the idea that all exceptions that you made should derive it. Fair point, your should be able to handle your own exceptions, right? The problem is what nobody used it and therefore Microsoft changed it’s recommendation to NOT use it. It’s just lying there in the framework like an old aunt that just don’t want to go away (I still love you all my dear aunts).

InvalidOperationException is also an exception that should be blown to hell. The description of the exception says this:

The exception that is thrown when a method call is invalid for the object’s current state.

What does that mean in the real world? When do exceptions get thrown in general? Well. When something unexpected have happened, as in when a method is called when it isn’t supposed to be. How else can an exception be raised? When not calling a method?

The InvalidOperationException is really like an Exception in a disguise. Try to search in a couple of open source projects after it (or your own). It’s thrown a lot. It’s a poor mans choice to exception handling. Ohhh, I’ve been guilty one too many times too. It’s so handy since it can be applied to all exceptional cases.

The reason to why I wrote this post is that I was debugging an ASP.Net MVC application and found that MS throws it when an action cannot be found in a controller. The result is that a Internal Server Error page is shown instead of a File Not Found page. Sure, it’s an error in the application and the proper controller have been found. But do the browser care about which framework is used in the web server? No. File not found is therefore the proper status code.

Microsoft should have created an ActionNotFound exception instead and derived it from HttpException (and set the 404 status code in the constructor initialization).

Edit:
I’ve filed a bug report for ASP.Net MVC: http://aspnet.codeplex.com/workitem/7588

Do NOT catch that exception!

Ohhh, I’ve recently seen one to many application where the developers try to be safe by catching exceptions all over the place. It can be everything from a small simple method that doesn’t throw that many exceptions to a large method with multiple try/catch statements. Most of those catch blocks just logs the exception and rethrow it.

This post discusses how those problems can be solved.

Ohhh, I’ve recently seen one to many application where the developer try to be safe by catching exceptions all over the place. It can be everything from a small simple method that doesn’t throw that many exceptions to a large method with multiple try/catch statements. Most of those catch blocks just logs the exception and rethrow it.

Please do not catch that exception. Let it travel down the call stack. I promise you that you won’t regret it. You’ll get a warm and fuzzy feeling next time you’ll test your application. I promise you! Really!

Why? You’ll get a complete exception with all the details you need to fix the error, it’s very easy to loose information if you catch/wrap/rethrow exceptions . The problem with all of those try/catch blocks is they doesn’t help your application in any way. They just clutter up the code and your log files.

If you still want to catch exceptions: I’ll try to explain the way to do it.

Catching exceptions in the correct way.

Yeah. Proper exception handling can be something wonderful. You’ll smile every time you get an exception. First of all: Exceptions only happens when something exceptional occurs.  Please have that in mind, because it helps you remember that you don’t need those try/catch block everywhere.

That brings us to the golden rule about when to catch exceptions:

Only catch exceptions that you can handle to rescue the situation.

That means that you should only catch exceptions if you, by handling it, can let the application continue as (almost) expected. Let me rephrase that: Only catch a exception if you, by catching it, can let the method return a result as promised.

There are of course exceptions, namely two of them:

Do not let layer specific exceptions propagate up the call stack.

For instance, if the data layer fails and throws a SqlException (if you are using Sql Server) you should catch it and wrap it inside a more generic exception. Create a DataSourceException which could be used even if you switch data source from a database to a Web Service. You should of course add details to the exception such as the method name, parameters or anything else that can be useful. Do NOT forget to add the original exception as  inner exception.

public class UserRepository : IUserRepository
{
    public IList<User> Search(string value)
    {
        try
        {
              return CreateConnectionAndACommandAndReturnAList("WHERE value=@value", Parameter.New("value", value));
        }
        catch (SqlException err)
        {
             var msg = String.Format("Ohh no!  Failed to search after users with '{0}' as search string", value);
             throw new DataSourceException(msg, err);
        }
    }
}

Update 2013-03-01: I’m not following this rule any more. The only time I wrap exceptions is if I add more context information to help me prevent the exception in the future. It doesn’t really matter if the data layer exception is passed up the call stack, since it won’t be handled but just logged in the top layer

If you don’t want to display data layer specific information to the user, then simply display something like "An unexpected error occurred" instead of showing exception information. The exception information doesn’t really help your user either way.

Try/Catch all is OK in the layer closest to the user.

Ok, so you have let the exceptions propagate through all your layers to the presentation layer (winforms/asp.net etc). Fine. Go ahead, give the user some fancy error pages. Also log those errors. But just don’t log them. Notify a support team. Send an email to the project lead.

When everything else fails

Are you not sure that your new exception policy will catch all of those exceptions? Is it scary? The I got the solution for YOU!

Asp.Net Implement Aplication_OnError(object source, EventArgs e) in your global.asa. It will be called for all unhandled exceptions.
WinForms Subscribe on Application.ThreadException
WinServices Subscribe on AppDomain.CurrentDomain.UnhandledException. The problem with this event is that it will still terminate the application. But there’s a way around that too.
WCF WCF: Implement IErrorHandler and log the exceptions in it (added 2013-03-01).
ASMX ASMX: Create a custom Soap Extension. (added 2013-03-01).

In the next blog post I’ll discuss common mistakes in those catch blocks and how your tailor made exceptions should look like.

Update 2013-04-17

I’ve written a new exception series. Starting with What are exceptions?

My name is More, Docu More!

Are you one of those people that thinks that code is self explainable? Still thinking that when you go back and try to fix code that you did a year ago? Yes? Good for you.

Documentation is a tool that is quite underrated. If used in the right way, it can improve your coding skills. Seriously!

I got a few guide lines that I try to follow when coding. (Sure, sometimes I don’t give a sh!t. We are only humans, right?)

Rule 1: There are no rules

If you do not intend to follow your rules, don’t make them. It’s quite easy to make a lot of rules that will, if you use them, improve your code quite a lot. But you need to use them, right?

If you feel that you have too many rules, simply remove those that you break most often. When you have started to follow all your rules, add another one (if necessary).

Rule 2: Describe the purpose

When documenting projects and classes, ALWAYS motivate why you created them. If you can’t write a clear and concise motivation to why a class was created, you have probably done something wrong. Refactor.

Rule 3: AND is evil

Do not write a lot of AND in your code documentation. If you do, read about single responsibility principle in a previous post.

Example:

This method will save the user, email the admin and save a blog entry into the database.

Rule 4: Explain what parameters do, not what they are

I quite often see documentation which just describes what parameters are (their type), but not what they are used for or what business rules they are validated against.

Coding contracts will be a big help here, since they are also imported into the documentation.

Rule 5: Return values are not obvious

Return values are not obvious. Can null be returned? What is no users are found, is null or an empty list returned? Always describe the return values.

If you find yourself describing more than two different type of return values, check if you should refactor the method.

Example of a good description (for the method GetUser): The requested user if found; otherwise null.

Rule 6: Exceptions

Are you always throwing/catching Exception instead of more specific exceptions? Stop. Read here and here

Ohh. We are talking about DOCUMENTING exceptions, not about how to use them. Well. Just document them….

Final words

Have you ever started to work out? You create a wonderful exercise program and decide to go the gym four times a week. It looks really good on paper, but how long do you keep it up? It’s the same with documentation. Start small. Download GhostDoc (see below) and start describing the purpose of each project/class/method. Do that for a week or two. Feels good? Do more.

Tools

GhostDoc helps you document your stuff in Visual Studio. When done, use Sandcastle to generate the docs. You might want to wrap sandcastle with a more user-friendly GUI.