When to return null and when to throw an Exception?

| | Comments (0)

I am pretty sure once you transcend the youth phase of software development, and you start thinking about what you are actually doing whilst writing code, you'll start running into tough decisions such as when to throw an exception, and when to return null.

I found a simple way of resolving this controversy. Before answering that question, you need to ask yourself "Would it be beneficial to the caller if the code throws an exception or would it be more beneficial if I return null". This refers both to the code and the programmer. I say this since returning null is generally regarded as a Bad Thing, since the onus is on the developer to ensure the return result is checked. However, there are scenarios in which it is better to return null.

Lets focus for a moment on framework design. This is a bit different since many people will be using your code and be absolutely dependent on the way you return from the function call, whilst writing application code you normally tend not to invoke a method that regularly, thus if you made a mistake it should not be that terrible.

Consider the following piece of code in pseudo language:

  function newestDate(Date Date1, Date Date2) returns Date
    if Date1 is null or Date2 is null
      return null   
 
    if Date1 before Date2
      return Date2
    else
      return Date1
  end function

This method returns null on invalid input. Some developers call this technique GIGO (Garbage In Garbage Out). While in principle this might seem attractive and simple - i.e. you do not end up with anything worse than you had, it is not a good thing to do in this case. I say this because of the intent of the method newestDate(). This method evaluates which of the two dates are the newest. Possible return values are (ignoring the case where Date1 == Date2):

  • Date1 is the newest
  • Date2 is the newest
  • Cannot perform comparison since Date1 and/or Date2 is null

The first two return values are trivial. It is the last one that deserves some careful thought. There are four ways to return from the function if the third return value holds, namely:

  • Date1 is null and Date2 not, thus Date2 must be the newest
  • Date2 is null and Date1 not, thus Date1 must be the newest
  • Date1 and Date2 are null, thus no comparison can be performed so either return null or throw exception
  • Date1 and/or Date2 is null, which implies no comparison can be performed thus return null or throw an exception

All of these are valid assumptions - none of them are fundamentally wrong. It is merely a matter of choosing the best one for the intent of the specific function. The benefit of returning null is simplicity - the caller does not have to catch the exception if this is an expected (i.e. normal) condition - the code flow is thus neater. The con is that the onus is on the developer to ensure the null return value is not used anywhere, and checked on return of this method. If this is not done, it may be difficult to determine the cause of the NullPointerException error that is bound to happen. Returning null is thus a tradeoff between simplistic code flow versus developer responsibility. Throwing an exception is exactly the opposite. A benefit is that if the developer does not think about this scenario it will not be difficult to troubleshoot since the exception will be propagated up the call stack with a detailed error message. The con is that if this is an expected condition, it is more work to catch the exception every time and handle it.

I personally prefer the exception - rather let the developer work a little bit harder when a scenario such as this occurs, so that handling of a null date can be coded for properly. If the developer is lazy and we made use of a RuntimeException, at least it will take only a blink of the eye to pinpoint the source of the problem. However if we returned null, the onus is on the developer to RTFM and ensure the return date is checked properly. Since developers do not read manuals, this is a bad assumption to make.

In another example, consider this:

  function toIntegerArray(Object[] pArray) returns Integer[] 
    if pArray is null
      return null

    // Build array
    ...

    return vArray
  end function

Here I opted to return null since converting a null array to an integer array, is still a null array. This is mathematically correct. Throwing an exception would not really be justifyable here.

The decision to return null or to throw an exception is not trivial to make, but as a rule of thumb use this solution: If in doubt, throw an exception. Only if you are absolutely confident it makes mathematical sense to return null, proceed.

Leave a comment


Type the characters you see in the picture above.