Exception Handling – Exception vs Empty Result Set for Technically Valid but Unsatisfiable Inputs

exceptionslibrariespatterns-and-practices

I'm developing a library intended for public release. It contains various methods for operating on sets of objects – generating, inspecting, partitioning and projecting the sets into new forms. In case it's relevant, it's a C# class library containing LINQ-style extensions on IEnumerable, to be released as a NuGet package.

Some of the methods in this library can be given unsatisfiable input parameters. For example, in the combinatoric methods, there is a method to generate all sets of n items that can be constructed from a source set of m items. For example, given the set:

1, 2, 3, 4, 5

and asking for combinations of 2 would produce:

1, 2
1, 3
1, 4
etc…
5, 3
5, 4

Now, it's obviously possible to ask for something that can't be done, like giving it a set of 3 items and then asking for combinations of 4 items while setting the option that says it can only use each item once.

In this scenario, each parameter is individually valid:

  • The source collection is not null, and does contain items
  • The requested size of combinations is a positive nonzero integer
  • The requested mode (use each item only once) is a valid choice

However, the state of the parameters when taken together causes problems.

In this scenario, would you expect the method to throw an exception (eg. InvalidOperationException), or return an empty collection? Either seems valid to me:

  • You can't produce combinations of n items from a set of m items where n > m if you're only allowed to use each item once, so this operation can be deemed impossible, hence InvalidOperationException.
  • The set of combinations of size n that can be produced from m items when n > m is an empty set; no combinations can be produced.

The argument for an empty set

My first concern is that an exception prevents idiomatic LINQ-style chaining of methods when you're dealing with datasets that may have unknown size. In other words, you might want to do something like this:

var result = someInputSet
    .CombinationsOf(4, CombinationsGenerationMode.Distinct)
    .Select(combo => /* do some operation to a combination */)
    .ToList();

If your input set is of variable size, this code's behaviour is unpredictable. If .CombinationsOf() throws an exception when someInputSet has fewer than 4 elements, then this code will sometimes fail at runtime without some pre-checking. In the above example this checking is trivial, but if you're calling it halfway down a longer chain of LINQ then this might get tedious. If it returns an empty set, then result will be empty, which you may be perfectly happy with.

The argument for an exception

My second concern is that returning an empty set might hide problems – if you're calling this method halfway down a chain of LINQ and it quietly returns an empty set, then you may run into issues some steps later, or find yourself with an empty result set, and it may not be obvious how that happened given that you definitely had something in the input set.

What would you expect, and what's your argument for it?

Best Answer

Return an Empty Set

I would expect an empty set because:

There are 0 combinations of 4 numbers from the set of 3 when i can only use each number once

Related Topic