design: Why does consumeGas panic & not return an error?
- Dominant language
- Go
- Stars
- 416
- Forks
- 538
- PR merge metrics
- No merged PRs in 30d
Description
[func (k Keeper) consumeRuntimeGas(ctx sdk.Context, gas uint64) ](https://github.com/CosmWasm/wasmd/blob/d0dde1a0f12c93507f5b0842968dd4588b5df043/x/wasm/keeper/keeper.go#L1111-L1118) panics in function calls such as [`Sudo`](https://github.com/CosmWasm/wasmd/blob/d0dde1a0f12c93507f5b0842968dd4588b5df043/x/wasm/keeper/keeper.go#L538-L541) calls even though an error for this function is thrown
For developers, this is unexpected behavior, especially when using a childCtx with a gas limit, expecting an error to be thrown.
It then required work around like the following from Juno with a `recover()`
```go
// Execute contract, recover from panic
func ExecuteContract(k wasmtypes.ContractOpsKeeper, childCtx sdk.Context, contractAddr sdk.AccAddress, msgBz []byte, err *error) {
// Recover from panic, return error
defer func() {
if recoveryError := recover(); recoveryError != nil {
// Determine error associated with panic
if isOutofGas, msg := IsOutOfGasError(recoveryError); isOutofGas {
*err = ErrOutOfGas.Wrapf("%s", msg)
} else {
*err = ErrContractExecutionPanic.Wrapf("%s", recoveryError)
}
}
}()
// Execute contract with sudo
_, *err = k.Sudo(childCtx, contractAddr, msgBz)
}
// Check if error is out of gas error
func IsOutOfGasError(err any) (bool, string) {
switch e := err.(type) {
case storetypes.ErrorOutOfGas:
return true, e.Descriptor
case storetypes.ErrorGasOverflow:
return true, e.Descriptor
default:
return false, ""
}
}
```
This just seems wrong given Sudo already returns an error, so persist a Gas error up?
Contributor guide
Assessment
This issue has not been assessed yet.