# 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.