4

Most of the code I read out in the wild follow the precondition pattern if (condition) throw;

But this approach is cumbersome for clients to read. For example, with web3js you would have to check if the full consumption of gas means that a throw happend or you ran out of gas. With Geth at least you can examine the callstack for an invalid jump via debug.traceTransaction()

It seems much more appropiate to follow this approach:

if (condition) 
{
 ExceptionEvent();
 return ERRCODE;
}

By doing that you are capable getting the exception right.

Since using throw is so common in the codes I examined, what are possible drawbacks of my proposition, beside that you have to handle the error in all parts of the callstack correctly?

2 Answers 2

6

For example with web3js you would have to guestimate if the full consumtion of gas means that a throw happend or you ran out of gas

Guesstimation is unnecessary, you can get the estimated gas cost with:

let contract_instance = web3.eth.contract(abi).at(address); web3.eth.estimateGas( { from: web3.eth.defaultAccount, to: contract.address, data: contract_instance[method].getData.apply(null, args) });


beside that you have to handle the error in all parts of the callstack correctly

This IS the drawback. Especially once you get into inter-contract dependencies reverting every state-changing action is nearly impossible. And in an environment where the resulting state of the contract must always be known, throwing an exception is the best practice in this situation.

1
  • thanks, guestimating was clearly the wrong word. I wanted to express that I don't want to know what happened by comparing gas consumption alone, this is not a clean way. Also in many situations, it's preferable to know why an intent didn't succeed. And with multiple throws it's impossible to know. So manual graceful error handling FTW! Commented Dec 19, 2016 at 15:22
3

Throwing an exception makes it easier to reason about the resulting state on error. It's too easy to accidentally not revert all changes that were made on error if you return a value.

Future versions of the EVM will allow a throw construct which lets you read a value out even if state is reverted, and doesn't drain gas for the sub-call.

1
  • I come to the conclusion I should have read only assertion functions that are making the conditions testable before a state changing function call. that would allow me to know the reason why it would fail + having the state reverted without potential holes. Commented Dec 20, 2016 at 13:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.