Skip to content

Commit 38c1d59

Browse files
authored
abi/bind: fix error-handling in generated wrappers for functions returning structs (#22005)
Fixes the template used when generating code, which in some scenarios would lead to panic instead of returning an error.
1 parent 4d48980 commit 38c1d59

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

accounts/abi/bind/bind_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,45 @@ var bindTests = []struct {
569569
nil,
570570
nil,
571571
},
572+
{
573+
`NonExistentStruct`,
574+
`
575+
contract NonExistentStruct {
576+
function Struct() public view returns(uint256 a, uint256 b) {
577+
return (10, 10);
578+
}
579+
}
580+
`,
581+
[]string{`6080604052348015600f57600080fd5b5060888061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063d5f6622514602d575b600080fd5b6033604c565b6040805192835260208301919091528051918290030190f35b600a809156fea264697066735822beefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeef64736f6c6343decafe0033`},
582+
[]string{`[{"inputs":[],"name":"Struct","outputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"}],"stateMutability":"pure","type":"function"}]`},
583+
`
584+
"github.com/ethereum/go-ethereum/accounts/abi/bind"
585+
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
586+
"github.com/ethereum/go-ethereum/common"
587+
"github.com/ethereum/go-ethereum/core"
588+
`,
589+
`
590+
// Create a simulator and wrap a non-deployed contract
591+
592+
sim := backends.NewSimulatedBackend(core.GenesisAlloc{}, uint64(10000000000))
593+
defer sim.Close()
594+
595+
nonexistent, err := NewNonExistentStruct(common.Address{}, sim)
596+
if err != nil {
597+
t.Fatalf("Failed to access non-existent contract: %v", err)
598+
}
599+
// Ensure that contract calls fail with the appropriate error
600+
if res, err := nonexistent.Struct(nil); err == nil {
601+
t.Fatalf("Call succeeded on non-existent contract: %v", res)
602+
} else if (err != bind.ErrNoCode) {
603+
t.Fatalf("Error mismatch: have %v, want %v", err, bind.ErrNoCode)
604+
}
605+
`,
606+
nil,
607+
nil,
608+
nil,
609+
nil,
610+
},
572611
// Tests that gas estimation works for contracts with weird gas mechanics too.
573612
{
574613
`FunkyGasPattern`,

accounts/abi/bind/template.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,9 @@ var (
304304
err := _{{$contract.Type}}.contract.Call(opts, &out, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}})
305305
{{if .Structured}}
306306
outstruct := new(struct{ {{range .Normalized.Outputs}} {{.Name}} {{bindtype .Type $structs}}; {{end}} })
307+
if err != nil {
308+
return *outstruct, err
309+
}
307310
{{range $i, $t := .Normalized.Outputs}}
308311
outstruct.{{.Name}} = out[{{$i}}].({{bindtype .Type $structs}}){{end}}
309312

0 commit comments

Comments
 (0)