Skip to main content

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)
t.Log(err)
require.Error(t, err)
}

The t.Log(err) line will produce the following output:

tutorial_test.go:94: WASM: panic in VM: missing mandatory str

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.