0

Is there a way to persist event from contract even in case of error? Currently the deposited event seems to disappear when error occurs in contract.

1
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking.
    – Community Bot
    Aug 10, 2022 at 7:21

1 Answer 1

2

Currently the deposited event seems to disappear when error occurs in contract.

In the following I assume that by "error occurs" you mean that the contract either traps or returns a Result::Err.

Trapping happens typically when a contract panics on e.g. expect or unwrap or reentrancy (which is disabled by default). In the case of the contract trapping all side-effects are rolled back, so no storage changes are persisted and no events are emitted.

Returning a Result::Err results in the same behavior, the side-effects are rolled back and the Err(…) is returned in an output buffer, which can be displayed by UI's or CLI clients.

You have two options for your case:

(1) Return a Result<Result<…>>. So pseudo-code:

type MyBusinessLogicResult<T> = Result<T, MyErrors>;

#[ink(message)]
pub fn foo(&mut self) -> Result<MyBusinessLogicResult<…>> {
  self.env().emit_event(MyEventIndicatingAnError);
  Ok(MyBusinessLogicResult::Err(…))
}

It's important to know that here any side-effect before the Ok(…) would be persisted to chain storage! This is likely not what you want, bringing us to option (2).

(2) Use RPC's for determining if an error would happen on a particular contract call invocation.

This is the preferred method. Your frontend executes an RPC call to dry-run the contract method. This is then synchronous and your UI will immediately know the Result that the invocation would yield.

You can immediately display an error to the user, enabling adjusting the input so that the call would succeed.

You only submit the extrinsic once this dry-run would yield Result::Ok.

The advantage here is that the user doesn't have to pay for getting just the error and the result is known immediately. Events are asynchronous, your frontend has to actively listen for them which is not such a nice user experience due to the UI having to display some "waiting" indicator.

If you're using polkadot-js as an API there is documentation on how to dry-run a contract call here.

1
  • ya this seems to be the only way to get the errors for now only downside being contract will always return ok Aug 12, 2022 at 10:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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