Parameter to control whether to throw an exception or return null – good practice

exceptions

I often come across methods/functions which have an additional boolean parameter which controls whether an exception is thrown on failure, or null is returned.

There are already discussions about which of those is the better choice in which case, so let's not focus on this here. See e.g. Return magic value, throw exception or return false on failure?

Let us instead assume that there is a good reason why we want to support both ways.

Personally I think such a method should rather be split in two: One that throws an exception on failure, the other that returns null on failure.

So, which is better?

A: One method with $exception_on_failure parameter.

/**
 * @param int $id
 * @param bool $exception_on_failure
 *
 * @return Item|null
 *   The item, or null if not found and $exception_on_failure is false.
 * @throws NoSuchItemException
 *   Thrown if item not found, and $exception_on_failure is true.
 */
function loadItem(int $id, bool $exception_on_failure): ?Item;

B: Two distinct methods.

/**
 * @param int $id
 *
 * @return Item|null
 *   The item, or null if not found.
 */
function loadItemOrNull(int $id): ?Item;

/**
 * @param int $id
 *
 * @return Item
 *   The item, if found (exception otherwise).
 *
 * @throws NoSuchItemException
 *   Thrown if item not found.
 */
function loadItem(int $id): Item;

EDIT: C: Something else?

A lot of people have suggested other options, or claim that both A and B are flawed. Such suggestions or opinions are welcome, relevant and useful. A complete answer can contain such extra information, but will also address the main question of whether a parameter to change the signature/behavior is a good idea.

Notes

In case someone is wondering: The examples are in PHP. But I think the question applies across languages as long as they are somewhat similar to PHP or Java.

Best Answer

You're correct: two methods are much better for that, for several reasons:

  1. In Java, the signature of the method which potentially throws an exception will include this exception; the other method won't. It makes it particularly clear what to expect from the one and the other.

  2. In languages such as C# where the signature of the method tells nothing about the exceptions, the public methods should still be documented, and such documentation includes the exceptions. Documenting a single method would not be easy.

    Your example is perfect: the comments in the second piece of code look much clearer, and I would even short “ The item, if found (exception otherwise).” down to “ The item.”—the presence of a potential exception and the description you gave to it are self-explanatory.

  3. In a case of a single method, there are few cases where you would like to toggle the value of the boolean parameter on runtime, and if you do, it would mean that the caller will have to handle both cases (a null response and the exception), making the code much more difficult than it needs to be. Since the choice is made not at runtime, but when writing the code, two methods make perfect sense.

  4. Some frameworks, such as .NET Framework, have established conventions for this situation, and they solve it with two methods, just like you suggested. The only difference is that they use a pattern explained by Ewan in his answer, so int.Parse(string): int throws an exception, while int.TryParse(string, out int): bool doesn't. This naming convention is very strong in .NET's community and should be followed whenever the code matches the situation you describe.

Related Topic