When do you throw an exception? I never asked myself that question until a few weeks ago when some guys on my team started wondering aloud. I suppose I never asked because I just threw exceptions whenever I felt like it. But the question on the minds of my colleagues has got me thinking too. When should I throw exceptions?

One team member says that exceptions should only be thrown when there is exceptional behavior. That sounds reasonable, right? But now, we have to define exceptional behavior. Google says that an exception is, “A person or thing that is excluded from a general statement or does not follow a rule.” So exceptional behavior is conduct that breaks rules, simply put.

Take the following code for example:

The purpose of the function is expressed in the function’s name: “Get a monkey by its ID.” So, what if there is no monkey found by the given ID? Is that exceptional behavior? If you were inclined to say, “no,” you could do a few things in response to your lack of monkey. You could return null, but that’s a cheap shortcut that will cause problematic code down the line. You could possibly change the method to return an object that contains a monkey, a success flag, and a message (for when there is no monkey found), like so:

So, then, your function can go something like this:

There is something wrong with that function that I REALLY don’t like. The MonkeyResponse class will ALWAYS return a null or some empty value. If there is a monkey found, it will return a null/empty message. If there is no monkey found, the monkey property will be null. Neither of those options are satisfactory.

The fact of the matter is, there is a rule being broken in this function when an invalid ID is passed in. The function’s purpose is to retrieve a monkey. If that is not possible, then the code’s course has to change drastically from it’s intended purpose. We need to call a spade a spade, address the broken rule appropriately, and throw an exception.

Here’s my refactored function including an exception:

I got rid of the MonkeyResponse object because I don’t need it anymore. Now, my function returns a Monkey if one is found, and throws an exception when someone passes in an invalid ID. This feels much better. I know that the repo is returning a null when no monkey can be found, but that’s a refactor for another day. I would probably move the exception from this function into the repo function and let the exception bubble up.

This really isn’t rocket science, but I think it’s important to question your methods from time to time. I’ve been throwing exceptions (on purpose) without justification for years. Now, I have at least gone through the thought process of justifying my methods. In a nutshell, here’s what I’ve come up with:

Throw an exception when a function’s behavior breaks the rules and causes the code to change course as a result.

  • Anonymous

    Good article, Byron.  The phrase “Exceptions should be exceptional” is used frequently, but I don’t find it to be very informative.  Of course exceptions are exceptional … and chocolate is chocolaty!  

    • Anonymous

      Chocolate should be chocolaty or else people will easily identify it as false. But I’ve found Exceptions to be a little more elusive… people, including me, have thrown exceptions for all kinds of reasons, many of which are not actually exceptions to rules (exceptional). Sometimes a statement of the obvious (“Exceptions should be exceptional.”) helps bring us back to reality.

      • Anonymous

        I’d agree the phrase is a good conversation starter and perhaps a witty title for an article, but it makes for a poor definition as you demonstrated by the need to define what exceptional actually means.  

        Those who use the phrase “Exceptions are exceptional” generally mean that exceptions should be used for errors that are “out of the ordinary”, but I would disagree with this.  Exceptions are for errors.  What defines an error is dependent upon the context.  

        In the MonekyRepository.GetById() example, I would agree that this could be an error (or a “rule breakage” as you’ve described it) and therefore an appropriate place to throw an exception, but not merely because the Monkey didn’t exist.  The phrasing of the method (i.e. Get) presumes the client expects the query to return a Monkey, so it would be an error if a Monkey wasn’t returned.  If the purpose of the method were merely to inquire if a Monkey by some given criteria existed (e.g. FindBy[some criteria]()), then the absence of a Monkey matching the provided criteria wouldn’t be an error.  So, it all depends on context.

        For an in-depth discussion on this topic, I’d recommend reading the chapter on Exceptions in the book “Framework Design Guidelines”.

        Good thought provoking article.  Keep ‘em coming!

        • Anonymous

          You’re absolutely right! I believe we’re on the same page. Thanks for your great comments.

      • Anonymous

        I’d agree the phrase is a good conversation starter and perhaps a witty title for an article, but it makes for a poor definition as you demonstrated by the need to define what exceptional actually means.  

        Those who use the phrase “Exceptions are exceptional” generally mean that exceptions should be used for errors that are “out of the ordinary”, but I would disagree with this.  Exceptions are for errors.  What defines an error is dependent upon the context.  

        In the MonekyRepository.GetById() example, I would agree that this could be an error (or a “rule breakage” as you’ve described it) and therefore an appropriate place to throw an exception, but not merely because the Monkey didn’t exist.  The phrasing of the method (i.e. Get) presumes the client expects the query to return a Monkey, so it would be an error if a Monkey wasn’t returned.  If the purpose of the method were merely to inquire if a Monkey by some given criteria existed (e.g. FindBy[some criteria]()), then the absence of a Monkey matching the provided criteria wouldn’t be an error.  So, it all depends on context.

        For an in-depth discussion on this topic, I’d recommend reading the chapter on Exceptions in the book “Framework Design Guidelines”.

        Good thought provoking article.  Keep ‘em coming!

  • The Damn Steve

    I believe the exceptions should only be thrown when there is exceptional behavior idea is poorly alluding to the question of is it part of a normal business process.  There are few applications that actually have people looking up monkeys by id, but I have worked on quite a few that were all about looking up a monkey by name.  Typing a name incorrectly is likely.  Monkey names are all consonants.  Just as likely is someone trying to locate a monkey that has recently gone on to monkey heaven.  Either way, handling the behavior with exceptions is probably a bad idea.  You should probably design the system to return an empty list of monkeys.  Maybe a magical “invalid monkey search” monkey would work.  Returning a status of a monkey search is right out.  It is possibly the worst idea I have ever seen on your blog.  I’m with you on throwing an exception if you receive an invalid primary key though.  Very rarely is there a business process for that.

    Also, throwing an exception doesn’t gain you much over returning null.  You still have to depend on the developer calling your code to handle it correctly.  Once the exception hits a proxy or webservice boundary they might even change types or get wrapped up in some pretty xml.  Having said that, NEVER EVER EVER return null.