Error Handling
The following test posts a request to the solotutorial
smart contract without the expected parameter "str"
, causing
the smart contract call to panic:
func TestTutorialInvokeSCError(t *testing.T) {
env := solo.New(t, &solo.InitOptions{AutoAdjustStorageDeposit: true})
chain := env.NewChain()
err := chain.DeployWasmContract(nil, "solotutorial", "solotutorial_bg.wasm")
require.NoError(t, err)
// missing the required parameter "str"
req := solo.NewCallParams("solotutorial", "storeString").
WithMaxAffordableGasBudget()
_, err = chain.PostRequestSync(req, nil)
require.Error(t, err)
require.True(t, err.Error() == "WASM: panic in VM: missing mandatory string")
}
The _, err = chain.PostRequestSync(req, nil)
will return an error containing WASM: panic in VM: missing mandatory string
.
This shows that the request resulted in a panic.
The Solo test passes because of the require.Error(t, err)
line.
Note that this test still ends with the state #4
, although the last request to the smart contract failed:
20:09.974258867 INFO TestTutorialInvokeSCError.ch1 solo/run.go:156 state transition --> #4. Requests in the block: 1. Outputs: 1
This shows that a chain block is always generated, regardless of whether the smart contract call succeeds or not. The
result of the request is stored in the chain's blocklog
in the form of
a receipt. In fact, the received Go error err
in the test above is just generated from the request receipt.
If a panic occurs during a smart contract call, it is recovered by the VM context, and the request is marked as failed. Any state changes made prior to the panic are rolled back.