Should a retrieval method return null
or throw an exception when it can't produce the return value?
Your approach should depend on expected outcomes: return null
when the value might be absent; throw an exception when its absence denotes an error. In simpler terms:
Find (Optional fetch for a user) = null
is cool.
Get (Mandatory fetch for a user) = Yell out (exception) if the user is missing!
Your approach needs to be predictable and consistent all across your code. Documentation can be your best friend!
Dealing with null
Returning null
makes sense when the absence of a value is, well, normal. This typically happens in:
- Lookup operations (a user might not exist in your system).
- Indicating that there are no operations to be performed.
- Scenarios where your program can handle
null
without going kaput.
In scenarios where null
is a possible response, consider using Optional class to amplify clearer intentions:
Exceptions: not always exceptional!
An exception is thrown when the absence of a return value signals an error. They match scenarios like:
- Guaranteed results (like fetching system configuration data).
- Processing that depends on a successful retrieval (like processing a payment).
- Critical business processes where missing entities mean big trouble!
Keeping it consistent
By maintaining consistency you can prevent headaches down the road:
- Establish error handling policies at the project or team level.
- Document and use clear naming conventions.
- Helper methods can abstract
null
checks and exception throwings. Less code, more fun!
Intuition for the rescue
Avoid misleading or ambiguous values. Instead:
- Use exceptions to provide a detailed breakdown of what went wrong.
- Use return values that don't make developers guess what they mean.
Domino effect: implications on existing code
Consider the side effects on the calling code:
- Having to include
null
checks everywhere can lead to messy and hard-to-read codes. - Exceptions can make control flow hard to predict and may demand additional handling logic claims.
- The chosen approach should minimize the "surprise element" for the developers.
The lost art of expressing intentions in code
Code should be as expressive as a book. Well-known patterns like Null Object pattern or Factory Method pattern can be helpful to make your coding intentions explicitly known.
Specific use cases = specific strategies
Always analyze the specific use case:
- Is the absence of a value hinting at a problem?
- Can the method's contract tolerate a
null
value? - Do you want to force the calling code to deal with a possible absence?
Dealing with complexity
As your app grows and gets complicated, your error handling strategies can have profound effects:
- The performance impact of creating exceptions should be considered for high load scenarios.
- Predictable error handling strategies make for easier testing and debugging.
- Security matters! Make sure exceptions don't leak sensitive info.
Was this article helpful?