When To Use Exceptions

Marty Alchin recently posted about the “evils” of returning None (or nil or null depending on your language of choice). I think he has it basically right. Sure there are situations where returning nil1 is appropriate, but they are pretty rare. For example, if a method actually does what the client asked and there is nothing meaningful to return, then by all means return nil. If, however, the method was not actually able to do what the client asked, raising an exception is the appropriate thing to do. Unfortunately, I think that most methods that return nil in modern libraries and programs actually do so as a way to indicate a failure condition, and that is evil.

Cédric Beust responded to Mr Alchin saying basically, a) “problems caused by returning null are easy to debug” and b) “programmers are all knowing, about now and the future, so they can decide when to return nil and when to raise an exception.” (I am, as you might have guessed, taking significant liberties in my para-phrasing. You should go read Mr Beust’s post if want to know what he actually said.)

Ease of debugging

On the debugging point I would say that Mr Beust is generally correct. It is usually the case that nil returns are fairly easy to debug. However, this is not always true. In fact, it is not uncommon, in my experience, to find a nil where it is not suppose to be but then to spend a fair bit of time tracking down where that value became nil. That time is usually spent walking my way up the call stack trying to find the subtle bug that results in a nil return from a method in only some odd situations.

That sort of debugging is not the end of the world but it is annoying particularly because it is so easily avoidable.

All knowing programmers

To be fair, Mr Beust did not actually say that he believes that programmers are all knowing. But he did describe a way of using exceptions that would only make sense if programmers were all knowing. From that, one might infer that he does believe that programmers are in fact omniscient. In my experience this misconception is fairly common in the Java community (Actually, this mentality exists to varying degrees in most programming communities) . Java itself includes many decisions that seem only to make sense in the presence of this assumption. But I digress.

The statement to which I am referring is

Here is a scoop: exception should only be thrown for exceptional situations. Not finding a configuration value is not exceptional. Not finding a word in a document is not exceptional: it can happen, it’s even expected to happen, and it’s perfectly okay if it does.

My response to this is: Who exactly are you to decide that not finding a configuration value is a non-exceptional event for my application? Library programmers2 should not be deciding what is and is not an “exceptional” event. That is a value judgement they cannot possibly make correctly, unless they understand every way that every program will make use of that library (or class) in perpetuity.

Exceptions are not about “exceptional situations”, whatever that means. They are a way for methods tell their caller that it was not able to do what the caller asked it to do. If I say, “dictionary give me the value associated with a particular key” and the key does not exist, the appropriate response is a NoSuchKey exception. Returning a nil in that situation is a lie. A lie with real, and negative, consequences. Consider this, I ask a dictionary for the value associated with a key and it returns nil. Does that mean the key does not exist, or that the key does exist and it’s value is nil? Those two are very different but a nil returning method conflates them requiring, at the very least, an addition method call figure out which possibility is actually the case.

If having methods actually inform you of their inability to perform the desired action is complicated or hard to understand it is time to upgrade your language or write a better interface. For example, if catching an exception from a dictionary look up complicated for the cases where you just want to use a default value, that exception catching and default value behavior could easily be put in a get_with_default(key, default_value) method that either returns the value from the dictionary or the default value. That would certainly be clearer than returning nil and having every consumer add an ugly if block after the get. Or you could switch to a language (such as Ruby) with a compact single line exception handling syntax.

Either way my advice is: Do not use nil as a way to indicate that the object was unable to perform the requested operation, that is job of exceptions. If you see a method that returns nil demand an affirmative defense for that behavior because it is often incorrect.


  1. nil is the Ruby equivalent of None in Python and null in Java. Since all other programming languages are but pale shadows in comparison to Ruby I shall hence forth be using nil to describe this concept.

  2. By library programmer I mean someone that is writing code that will be used by someone else at some point in the future. If that does not include you it is because a) you are not a programmer or b) you are writing completely unmaintainable spaghetti code.

Comments 5

  1. Tech Per wrote:

    Hmm, I seem to disagree a bit with you and agree a bit more with Cedric. I am not sure, though, cause when you say:

    “….Either way my advice is: Do not use nil as a way to indicate that the object was unable to perform the requested operation, that is job of exceptions…..”

    I can agree. IFF “..the object was unable to perform the requested operation..” means that the contract cannot be fulfilled. Now, in Java, we cannot always express all we want about contracts, as for example Eiffel can. But, we can do it in javadoc or sometimes by annotations. If, the method is documented to return null if nothing is found on a key lookup in a dictionary (to take your example), then by all means, returning null is the right thing to do. It is NOT exceptional, that the key doesn’t exist or the value is null. In Java, the Map class includes an contains method too.

    Now, I then get confused about what you really mean, when you write:

    “….Exceptions are not about “exceptional situations”, whatever that means. They are a way for methods tell their caller that it was not able to do what the caller asked it to do. If I say, “dictionary give me the value associated with a particular key” and the key does not exist, the appropriate response is a NoSuchKey exception. Returning a nil in that situation is a lie….”

    Cause hell yeahh, exceptions are about exceptional conditions only!! There are just not many programmers that recoqnize this, I think. Even Sun can make mistakes. I have always hated this construct from JEE:

    try {
    bean = beanHome.findByPK(…);
    // update bean here
    } catch (ObjectNotFoundException e) {
    // create bean here
    }

    That sucks. I have control logic (is this a create or an update) done with exceptions. Bwadrh! This should be a:

    bean = beanHome.findByPK(…);
    if (bean == null) {
    // create
    } else {
    // update
    }

    Have you considered using @Null/@NotNull annotations on methods together with a IDE that can use them for anything?

    Posted 25 Nov 2007 at 6:25 am
  2. Dan wrote:

    The environment may have something to do with the best approach. In Java, dealing with exceptions is a messy pain in the arse. There is also a lot of overhead associated with creating and throwing exceptions; because exceptions are supposed to be unusual, they are not optimized for.

    Using exceptions for unexceptional circumstances is considered an anti-pattern in Java. I would much rather have Map.get(“key”) return an ambiguous null and, if the distinction matters to me, use an idiom like if(!map.contains(“key”)) … else value = map.get(“key”); if(value == null) … than be forced to wrap every single Map access in my code with a try/catch block.

    Your example may make sense in Ruby (I don’t know Ruby well enough to have an opinion.) It doesn’t make sense in Java. Or perhaps the example was just poorly chosen?

    Posted 25 Nov 2007 at 12:07 pm
  3. Peter Williams wrote:

    Tech Per,

    In one sense you are certainly correct that a method should do what
    it’s documentation says it does. However, I consider that to be a bit
    of dodge. Merely documenting the behavior of a poorly thought out
    method does not somehow make it good (though that may be the only
    viable option for many existing methods).

    Most languages don’t good semantics for defining contracts, but that
    is OK (maybe even good). We get along just fine in the real world
    with out explicit, bullet proof, contracts. For example, when I go
    into my local coffee shop and say “give me a cup of dark coffee” I
    don’t have an explicit written contract with the person behind the
    counter but I would be really annoyed if they just handed me an empty
    cup. Of course they don’t do that, they say “sorry we are all out of
    dark coffee, do you want to wait while we brew more? That is, they
    raise an exception and let me decide what to do with it.

    There are a couple of possible definitions of “an exceptional
    situation”. I define it as a method not being able to do what the
    caller asked. Defining “an exceptional situation” any other way means
    that the library author really has to guessing about how the library
    will be used, and that never works out well.

    It ought to be fairly clear from the method name what is being asked
    (that is what we mean by “meaningful names”). A method like get
    should not be defined by the comments to mean “return the request
    thing unless it rhythms with shoe in which case append ‘… in bed’ to
    it and return that”. No, we know that when we say “get” we mean “go
    find the thing I am asking about and give it to me”. If the method
    cannot do that it should let the caller know that fact so that it can
    deal with it appropriately.

    If you need method that gets but appends ‘… in bed’ to the value (or
    returns some default value when the desired thing does not exist) by
    all means have one of those, but be sure to name it descriptively, so
    that every one knows what they are getting into.

    I do have so say that I find your first example a bit clearer than the
    second. However, I think what you really want is a “does a particular
    bean exist” predicate, e.g.

    if beanHome.beanWithPKExists(PkOfInterest) {
      bean = beanHome.findByPK(PkOfInterest);
    } else {
      bean = ...' // create bean here 
    }
    

    And then probably put block of code in a method like
    findOrCreateFooBean(). On the other hand if you have such a method
    the first form would be pretty good.

    As for annotations, I am not actively writing any Java at this point.
    I have in the past and may again in the future but currently I am
    using mostly Ruby.

    Posted 25 Nov 2007 at 4:14 pm
  4. Peter Williams wrote:

    Dan,

    It all comes down to defining “exception circumstance”. I don’t think
    you can reasonably define that from the application’s point of view,
    because that would require a deep understanding of all possible
    applications. If you accept that the only thing you are left with is
    to use the library’s perspective, which turns out to be reasonably
    tractable.

    But from that perspective you end up raising a lot more exceptions
    because a library does not know, or care, if an application is
    going to be able to operate without a configuration item that is
    missing or not, it only knows that the application asked for a
    configuration item and it is not able to provide that item. It is an
    exceptional circumstance because the application would not have asked
    for something it did not care about.

    As for messy syntax and inefficiency, I suggest that you never let
    perceived, or suspected, inefficiencies in the compiler or runtime
    impact coding decisions until you have profiles in hand showing that
    it actually matters. It almost never does.

    Syntax, though is a different issue. But you should think carefully
    before you trade try{...} catch{...} for ...; if(){}. There
    probably are situations where the second one is much better than the
    first but more often than not you are just bring the uncommon/error
    path into the main line flow of your code. That usually makes it
    harder to understand the intent of the code. Moving the handling
    exceptional circumstances (even those that are allowed, or even
    expected some of the time, like a missing configuration item) out into
    a catch block can have the effect of making the happy path a lot
    easier to understand.

    Posted 25 Nov 2007 at 10:24 pm
  5. Tech Per wrote:

    Hi Peter,

    I think you are right in one thing: That it all comes down to defining what an exceptional situation is. And, maybe, this is also what makes exceptions hard to use, and quite debated. Some even find that they have no place in a programming language. I guess this is also why I think we won’t agree on this subject :-)

    Now, about your example with the coffee shop. Hmm, well a bit far-fetched, I think but okay. If the mocha-master is telling you “sorry we are all out of dark coffee, do you want to wait while we brew more?”, this should then be directly transferable to the Map.get(“foo”) call saying ‘sorry, I am all out of values on key “foo”, do you want to wait for it to appear somehow, from somewhere?” :-)

    Happy hacking in Ruby. Now that’s fun !!

    Posted 26 Nov 2007 at 3:18 pm

Trackbacks & Pingbacks 1

  1. From “拥抱”异常,还是,“固守”返回值? | DCCMX - Performance & Security on 13 Nov 2011 at 9:14 pm

    […] When To Use Exceptions http://barelyenough.org/blog/2007/11/when-to-use-exceptions/ […]