Result Object vs Throwing Exceptions – Which Is Better?

error handlingexceptions

When sending a request to another module and expecting a result, it seems to me there are two ways of dealing with the 'non-happy paths'.

  • Throw an exception
  • Return a result object that wraps different results (such as value and error)

I would say the first one seems better in general. It keeps the code clean and readable. If you expect the result to be correct, just throw an exception to handle happy path divergence.

But what when you have no clue what the result will be?

For example calling a module that validates a lottery ticket. The happy path would be that you won, but it probably won't be. (As pointed out by @Ben Cottrell in the comments, "not winning" is also the happy path, maybe not for the end user, though)

Would it be better to consider that the happy path is getting a result from the LotteryTicketValidator and just handle exceptions for when the ticket could not be processed?

Another one could be user authentication when logging in. Can we assume that the user entered the correct credentials and throw an exception when the credentials are invalid, or should we expect to get some sort of LoginResult object?

Best Answer

You have to distinguish between return values and errors.

A return value is one of many possible outcomes of a computation. An error is an unexpected situation which needs to be reported to the caller.

A module may indicate that an error occurred with a special return value or it throws an exception because an error was not expected. That errors occur should be an exception, that's why we call them exceptions.

If a module validates lottery tickets, the outcome may be:

  • you have won
  • you have not won
  • an error occurred (e.g. the ticket is invalid)

In case of an error, the return value is neither "won" nor "not won", since no meaningful statement can be made when e.g. the lottery ticket is not valid.

Addendum

One might argue that invalid tickets are a common case and not an error. Then the outcome of the ticket validation will be:

  • you have won
  • you have not won
  • the ticket is invalid
  • an error occurred (e.g. no connection to the lottery server)

It all depends on what cases you are planning to support and what are unexpected situations where you do not implement logic other than to report an error.