Solidity Events – Good Practice to Log Event When Throwing?

eventsexceptionssoliditytransactionsweb3js

In Solidity (0.3.2) I am aware that there is no way to throw specific exceptions. (Everything is an invalid JUMP error.) It seems beneficial to have a way to log specific errors. Does it make sense to create an Error event to be fired before any exception? Are there any downsides I am not thinking of?

event Error(string message);

...

if(msg.sender != owner) {
  Error("User not authorized");
  throw;
}

EDIT: It appears that the event does not get logged at all if the transaction fails. Can someone confirm?

Best Answer

With an exception, as with throw, all effects (including events) of a transaction are reverted, except for the payment to the miner. So there would be no benefit in firing an event before a throw.


Possible Alternative

If full reversion via an exception isn't required, an error code might be usable.

Example:

contract C {
  function foo() returns(int) {
    if(msg.sender != owner) {
      Error("User not authorized")
      return -1111;  // some error code
    }
    // sender is authorized so do stuff
  }
}

Events can't be accessed by contracts so the error message is more for the frontend. If the message is just for the frontend, consider using a pattern of eth_call before an eth_sendTransaction (call vs sendTx explained here).

The eth_call before eth_sendTransaction pattern would look like this frontend Javascript code:

// `contract` is an instance, from web3.eth.contract(...).at(...)

if (contract.foo.call({from: eth.accounts[0]...) === -1111) {
  // example only of how error could be dealt with
  alert("User not authorized");  
  return;
}

// user should now be authorized (though it is possible another transaction may have changed `owner` in contract `C` after above eth_call and before this upcoming eth_sendTransaction)
contract.foo.sendTransaction({from: eth.accounts[0]......)

That said, there can be cases where creating an Error event is desired. For example, if your DApp wants analytics on how many errors have been encountered, how many are unauthorized errors, etc an Error event could be the way to go.

EDIT: When https://github.com/ethereum/solidity/issues/1686 is implemented, the example in the question would look like:

require(msg.sender == owner, "User not authorized");
Related Topic