This is something I’ve been thinking about a lot. When do I throw an exception? Do I program with exceptions? Do I catch those exceptions.
Consider this piece of code:
public Product GetProduct(int id) { //get the product, or null if not found Product p = //... return p; }
Now you can ask yourself the following question:
Is it ok to return null if the product is not found? After all, the calling layer assumes that we’ll be getting a Product, not a null.
So now the calling layer needs to check if the product != null.
It would be exceptional if no product was found.
So in my opinion you throw an exception if no product is found. And that get’s handled in the calling layer.
But on the other hand: if you would just return a null and test on that in the calling layer you would use less resources since exception throwing is expensive.
I’d still go with the first one since it goes better with my consume code thoughts.
But this is an agreement you need to make across your team, and across your API.
I’d say FindProductById returns null and GetProduct throws an InvalidArgumentException. That’s how most of the collection classes in .Net works. Then how to use GetProduct without breaking our execution:
if (ContainsProduct(id))
Product p = GetProduct(id);
Hmm…
When you expect that the given Id exists, and you did not find a Product for that Id: throw an exception.
When it is very possible that a Product cannot be found given the (user) input, return null, and handle it elsewhere.
(For instance when they (user) search on a business-key (like an invoice number for instance), it is possible that the user makes a typing error, so, I would not throw an exception in such a case, since it is not exceptional that a user makes an error).
And, I think the naming convention of HawVer makes it quite self-explaining as well.