Just thought I would chime in, in case this Q&A is useful to others. For brevity, just imagine I prefixed everything with in my opinion.
It's a very general question. I would segregate the situations into two cases:
- "No" is a valid answer to a question
- Something is wrong with the transaction
In the first case, return false
might be the way to go. For example, "Is it Monday?" - No. Nothing is especially wrong and "No" is a valid and expected response. Implicitly, the caller should be prepared for the possibility that "No" will come back and deal with it accordingly.
A great number of cases fall into the second category; something is wrong. In these cases it's almost always preferable to throw;
in my opinion.
Consider that we can deploy a contract and then in the future the caller might be another contract. If we return false
we are, in effect, burdening the caller with the responsibility of contending with unexpected results. That leads to complexity and complexity is something we don't want in Smart Contracts. On the other hand, if we throw
at the first sign of trouble, we're doing a service to all future callers; if our function "didn't happen" then nothing happened.
This is quite the opposite of the philosophy in other environments where there is a near obsession with catching errors and explaining problems. I think it deserves mentioning for those starting out and possibly wondering about the customary approach.
In a Smart Contract, I tend to fail early, fail hard and explain nothing. In other words, throw
at (just about) every opportunity.
General heuristic:
- Validate input and throw if something is wrong.
- Do stuff.
- Check results and if something is wrong, throw.
- Return "success" or result.
It might seem a little brutal. A Smart Contract should in my opinion focus on safeguarding application (and data) integrity and it should do so in the simplest way possible because we're dealing with a platform on which an error or oversight could have non-trivial consequences and could be difficult or impossible to fix.
We're aiming for "obviously correct". Minimizing complexity implies that explaining the reasons is a separate concern (for clients to figure out). Throw
is usually the surest and simplest response to exceptions that threaten the integrity of the system.
Hope it helps.