Only throw an exception if it is truly an error. If it is expected behavior for the object to not exist, return the null. Otherwise it is a matter of preference. It certainly shouldn't be a matter of preference.
The FirstOrDefault method silently returns null if no order is found in the database. There are a couple of problems here: Callers of GetOrder method must implement null reference checking to avoid getting a NullReferenceException when accessing Order class members.
In short: You should throw an exception if a method is not able to do the task it is supposed to do.
In Java, a null value can be assigned to an object reference of any type to indicate that it points to nothing. The compiler assigns null to any uninitialized static and instance members of reference type. In the absence of a constructor, the getArticles() and getName() methods will return a null reference.
If you are always expecting to find a value then throw the exception if it is missing. The exception would mean that there was a problem.
If the value can be missing or present and both are valid for the application logic then return a null.
More important: What do you do other places in the code? Consistency is important.
Only throw an exception if it is truly an error. If it is expected behavior for the object to not exist, return the null.
Otherwise it is a matter of preference.
As a general rule, if the method should always return an object, then go with the exception. If you anticipate the occasional null and want to handle it in a certain way, go with the null.
Whatever you do, I highly advise against the third option: Returning a string that says "WTF".
If null never indicates an error then just return null.
If null is always an error then throw an exception.
If null is sometimes an exception then code two routines. One routine throws an exception and the other is a boolean test routine that returns the object in an output parameter and the routine returns a false if the object was not found.
It's hard to misuse a Try routine. It's real easy to forget to check for null.
So when null is an error you just write
object o = FindObject();
When the null isn't an error you can code something like
if (TryFindObject(out object o)
// Do something with o
else
// o was not found
I just wanted to recapitulate the options mentioned before, throwing some new ones in:
Or you might combine these options:
Provide several overloaded versions of your getter, so the caller can decide which way to go. In most cases, only the first one has an implementation of the search algorithm, and the other ones just wrap around the first one:
Object findObjectOrNull(String key);
Object findObjectOrThrow(String key) throws SomeException;
Object findObjectOrCreate(String key, SomeClass dataNeededToCreateNewObject);
Object findObjectOrDefault(String key, Object defaultReturnValue);
Even if you choose to provide only one implementation, you might want to use a naming convention like that to clarify your contract, and it helps you should you ever decide to add other implementations as well.
You should not overuse it, but it may be helpfull, espeacially when writing a helper Class which you will use in hundreds of different applications with many different error handling conventions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With