Ultimately, the state of your contract is the contract's responsibility, so it falls on the author to design in the assurances.
It might be helpful to break down the concerns to address with each step.
Is the input acceptable? If not, then either "Fail Early and fail hard" or return false. As a default approach, fail hard ensures the entire transaction reverts including all functions in all contracts that were involved. This relieves the caller of the responsibility for dealing with the "failed" case.
Optimistically update the contract to a new valid state assuming that interactions will be successful. This protects the contract from re-entrance and race conditions. For emphasis, it must be a completely valid new state.
balance[msg.sender] = 0;
.call() as well as
function calls to "untrusted" contracts. You should generally limit interactions to one "untrusted" contract. You must check the result and the compiler issues a warning when you don't.
If the called contract "fails hard" with
revert() then there is nothing to check. The whole thing will revert if something goes wrong. This is one of the advantages of using
transfer()to send ETH. If the contract
returns(bool success) then you need to check for the
false condition and decide what to do. This will always involve undoing the "optimistic accounting". If you want to carry on, then manually unwind it.
balances[msg.sender] += amount; // because we zeroed it out in step 2
If you do not want to carry on, you can revert the whole thing and return to the original state.
require(msg.sender.send(amount)); // this is what `transfer` does
Use it also for calling contract functions. If they return something, check it.
require(otherContract.doSomething()); // where it returns a bool
bool success = otherContract.doSomething();
// time to undo the "optimistic" accounting (effects) if we want to continue
If a transaction runs out of gas, the transaction will revert.
Much more could be said about the rationale for the pattern and non-obvious vulnerabilities that can emerge in contracts.
Hope it helps.