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