Transactions
Every contract invocation is wrapped into a transaction. If you know about transactions in SQL databases, you can consider them as the same basic concept. You execute multiple operations in a single transaction, and if one of them fails, the whole transaction is rolled back.
In our case, these operations are invocations of contract entrypoints. If one of the invocations in the chain fails, the whole transaction is usually rolled back. Failing in this context means that the contract entrypoint returns an error or panics.
Preventing rollbacks in case of failure
If you don't want your entire transaction to be rolled back in case of a failure, you can split the
logic into multiple messages. This can be two contracts, a contract executing itself or a contract
that sends a message to a Cosmos SDK module. Then use the reply_on
field in the message you send.
Set the field to one of the following values and instead of rolling back the transaction, you will
receive a message containing the error:
ReplyOn::Always
ReplyOn::Error
That way you can handle the error and decide what to do next, whether you want to propagate the error, retry the operation, ignore it, etc.
The default value ReplyOn::Success
means the caller is not ready to handle an error in the message
execution and the entire transaction is reverted on error.