views:

4485

answers:

30

I have a method that is suppose to return an object if it is found.

If it is not found, should I:

a) return null
b) throw an exception
c) other
+4  A: 

I prefer to just return a null, and rely on the caller to handle it appropriately. The (for lack of a better word) exception is if I am absolutely 'certain' this method will return an object. In that case a failure is an exceptional should and should throw.

swilliams
+7  A: 

Be consistent with the API(s) you're using.

dmckee
+7  A: 

Use the null object pattern or throw an exception.

pmlarocque
+1  A: 

If it's important for client code to know the difference between found and not found and this is supposed to be a routine behavior, then it's best to return null. Client code can then decide what to do.

plinth
+2  A: 

Generally it should return null. The code calling the method should decide whether to throw an exception or to attempt something else.

Eran Galperin
A: 

That really depends on if you expect to find the object, or not. If you follow the school of thought that exceptions should be used for indicating something, well, err, exceptional has occured then:

  • Object found; return object
  • Object not-found; throw exception

Otherwise, return null.

Rob
+23  A: 

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.

Carlton Jenke
+86  A: 

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.

Ken
@Ken: +1, it would be nice to mention that if you do throw an exception, but can detect it a priori (like HasItem(...)), then the user should provide said Has* or Contains method.
sixlettervariables
+9  A: 

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".

Matias Nino
+1 for suggesting against third option.
Chris Charabaruk
+3  A: 

Depends on what it means that the object is not found.

If it's a normal state of affairs, then return null. This is just something that might happen once in an while, and the callers should check for it.

If it's an error, then throw an exception, the callers should decide what to do with the error condition of missing object.

Ultimately either would work, although most people generally consider it good practice to only use Exceptions when something, well, Exceptional has happened.

Steve B.
A: 

It depends on the nature of the method and how it will be used. If it is normal behavior that the object may not be found, then return null. If it is normal behavior that the object is always found, throw an exception.

As a rule of thumb, use exceptions only for when something exceptional occurs. Don't write the code in such a way that exception throwing and catching is part of its normal operation.

Simon Howard
+1  A: 
warren
A: 

If not finding it is an exceptional event (i.e. it should be there under normal circumstances), then throw. Otherwise, return a "not found" value (can be null, but does not have to), or even have the method return a boolean for found/notfound and an out parameter for the actual object.

Nemanja Trifunovic
A: 

That depends on your method. If you method is supposed to always return a valid object and none is found, throwing an exception is the way to go. If the method is just ment to return an object which might or might not be there (like perhaps a image on a contact person) you shouldn't raise an error.

You might also want to expose a method returning a boolean true/false if this method actually will return an object so you don't have to either a) check for null or b) catch an exception

Per Hornshøj-Schierbeck
A: 

The "other" option could be to let the find method take an additional parameter with a default object that would be returned if the sought for object cannot be found.

Otherwise I'd just return null unless it really is an exceptional case when the object isn't found.

Christian Vest Hansen
+2  A: 

Return a null instead of throwing an exception and clearly document the possibility of a null return value in the API documentation. If the calling code doesn't honor the API and check for the null case, it will most probably result in some sort of "null pointer exception" anyway :)

In C++, I can think of 3 different flavors of setting up a method that finds an object.

Option A

Object *findObject(Key &key);

Return null when an object can't be found. Nice and simple. I'd go with this one. The alternative approaches below are for people who don't hate out-params.

Option B

void findObject(Key &key, Object &found);

Pass in a reference to variable that will be receiving the object. The method thrown an exception when an object can't be found. This convention is probably more suitable if it's not really expected for an object not to be found -- hence you throw an exception to signify that it's an unexpected case.

Option C

bool findObject(Key &key, Object &found);

The method returns false when an object can't be found. The advantage of this over option A is that you can check for the error case in one clear step:

if (!findObject(myKey, myObj)) { ...
Ates Goral
+2  A: 

Don't think anyone mentioned the overhead in exception handling - takes additional resources to load up and process the exception so unless its a true app killing or process stopping event (going forward would cause more harm than good) I would opt for passing back a value the calling environment could interpret as it sees fit.

ScottCher
A: 

I agree with what seems to be the consensus here (return null if "not found" is a normal possible outcome, or throw an exception if the semantics of the situation require that the object always be found).

There is, however, a third possibility that might make sense depending on your particular situation. Your method could return a default object of some sort in the "not found" condition, allowing calling code to be assured that it will always receive a valid object without the need for null checking or exception catching.

GBegen
A: 

In data layer code, I some times use the following code, allowing the caller to decide if "object not found" means an error has occured.


DataType GetObject(DBConnection conn, string id, bool throwOnNotFound) {
    DataType retval = ... // find object in database
    if (retval != null || ! throwOnNotFound) {
        return retval;
    } else {
        throw new NoRowsFoundException("DataType object with id {id} not found in database");
    }
}

DataType GetObject(DBConnection conn, string id) {
    return GetObject(conn, id, true);
} 
codeape
+12  A: 

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
Kevin Gale
This would be a more useful suggestion if C# provided real tuples, so we could avoid using an [out] parameter. Still, this is the preferred pattern, so +1.
Erik Forbes
In my opinion, the try approach is the best one. You don't have to look up then what happens if the object cannot be returned. With a Try method, you immediately know what to do.
OregonGhost
A: 

Or return an Option

An option is basically a container class that forces the client to handle booth cases. Scala has this concept, look up it's API.

Then you have methods like T getOrElse(T valueIfNull) on this object thet either return the found object, or an allternative the client specifieces.

John Nilsson
A: 

Return a null, exceptions are exactly that: something your code does that isn't expected.

Anders
+3  A: 

it depends if your language and code promotes: LBYL (look before you leap) or EAFP (easier to ask forgiveness than permission)

LBYL says you should check for values (so return a null)
EAFP says to just try the operation and see if it fails (throw an exception)

though I agree with above.. exceptions should be used for exceptional/error conditions, and returning a null is best when using checks.


EAFP vs. LBYL in Python:
http://mail.python.org/pipermail/python-list/2003-May/205182.html

Corey Goldberg
A: 

In some functions I add a parameter:

..., bool verify = true)

True means throw, false means return some error return value. This way, whoever uses this function has both options. The default should be true, for the benefit of those who forget about error handling.

Lev
A: 

It not containing the object can happen during normal operations and should be dealt with by the caller return NULL.

If not containing the object indicates a bug by the calling code or internal state then do an assert.

If not containing the object indicates an infrequent event. (Like someone deleted an item from the store while you were checking out the item at the same time.) Then throw an exception.

James Dean
+3  A: 

Just ask yourself: "is it an exceptional case that the object is not found"? If it is expected to happen in the normal course of your program, you probably should not raise an exception (since it is not exceptional behavior).

Short version: use exceptions to handle exceptional behavior, not to handle normal flow of control in your program.

-Alan.

AlanR
A: 

Exceptions should be exceptional. Return null if it is valid to return a null.

Andrew Lewis
More or less true. See http://www.boost.org/community/error_handling.html
Martin Cote
+1  A: 

Exceptions are related to Design by Contract.

The interface of an objects is actually a contract between two objects, the caller must meet the contract or else the receiver may just fail with an exception. There are two possible contracts

1) all input the method is valid, in which case you must return null when the object is not found.

2) only some input is valid, ie that which results in a found object. In which case you MUST offer a second method that allows the caller to determine if its input will be correct. For example

is_present(key)
find(key) throws Exception

IF and ONLY IF you provide both methods of the 2nd contract, you are allowed to throw an exception is nothing is found!

Adrian
+2  A: 

Here are a couple more suggestions.

If returning a collection, avoid returning null, return an empty collection which makes enumeration easier to deal with without a null check first.

Several .NET API's use the pattern of a thrownOnError parameter which gives the caller the choice as whether it is really an exceptional situation or not if the object is not found. Type.GetType is an example of this. Another common pattern with BCL is the TryGet pattern where a boolean is returned and the value is passed via an output parameter.

You could also consider the Null Object pattern in some circumstances which can either be a default or a version with no behaviour. The key is avoid null checks throughout the code base. See here for more information http://geekswithblogs.net/dsellers/archive/2006/09/08/90656.aspx

Duncan
+3  A: 

I just wanted to recapitulate the options mentioned before, throwing some new ones in:

  1. return null
  2. throw an Exception
  3. use the null object pattern
  4. provide a boolean parameter to you method, so the caller can chose if he wants you to throw an exception
  5. provide an extra parameter, so the caller can set a value which he gets back if no value is found

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.

Brian Schimmel