-
Type:
Bug
-
Resolution: Fixed
-
Priority:
Major - P3
-
Affects Version/s: 1.0.1
-
Component/s: None
-
None
-
None
-
Fully Compatible
-
None
-
None
-
None
-
None
-
None
-
None
Decoding to a nil pointer of a type panics.
This pattern works:
struct X {}
var x X
res.Decode(&x)
This pattern panics:
var x *X res.Decode(x)
This is subtle and users are likely to mess this up. We should detect this condition and return an instructive error instead of panicking and should document this limitation clearly.
We do this for other usage errors, such as "argument to Decode must be a pointer to a type, but got map[]".
Sample program:
package main
import (
"context"
"fmt"
"log"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)
type X struct {
ID primitive.ObjectID `bson:"_id,omitempty"`
Name string `bson:"name"`
}
func main() {
ctx := context.Background()
client, err := mongo.Connect(ctx)
if err != nil {
log.Fatal(err)
}
coll := client.Database("test").Collection("decodeit")
_ = coll.Drop(ctx)
doc := X{Name: "hello world"}
res, err := coll.InsertOne(ctx, doc)
if err != nil {
log.Fatal(err)
}
id := res.InsertedID
fmt.Println("Inserted", id)
got := coll.FindOne(ctx, bson.D{{"_id", id}})
if got.Err() != nil {
log.Fatal(got.Err())
}
var doc2 *X
err = got.Decode(doc2)
if err != nil {
log.Fatalf("doc2 %v", err)
}
fmt.Println("doc2", *doc2)
}
Output:
$ go run main.go
Inserted ObjectID("5cc65cd9731bafcc96ccb4f3")
panic: reflect: call of reflect.Value.Type on zero Value
goroutine 1 [running]:
reflect.Value.Type(0x0, 0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/reflect/value.go:1813 +0x169
go.mongodb.org/mongo-driver/bson.(*Decoder).Decode(0xc000083cb0, 0x140ce60, 0x0, 0x14567e0, 0xc000083cb0)
/Users/david/golang/pkg/mod/go.mongodb.org/mongo-driver@v1.0.1/bson/decoder.go:82 +0x25d
go.mongodb.org/mongo-driver/bson.unmarshalFromReader(0xc0000c2070, 0xc00005e400, 0x0, 0x0, 0x15f6ae0, 0xc00005e480, 0x140ce60, 0x0, 0x0, 0x0)
/Users/david/golang/pkg/mod/go.mongodb.org/mongo-driver@v1.0.1/bson/unmarshal.go:100 +0xff
go.mongodb.org/mongo-driver/bson.UnmarshalWithRegistry(0xc0000c2070, 0xc0000ce223, 0x2c, 0x5d, 0x140ce60, 0x0, 0x0, 0x0)
/Users/david/golang/pkg/mod/go.mongodb.org/mongo-driver@v1.0.1/bson/unmarshal.go:45 +0x10a
go.mongodb.org/mongo-driver/mongo.(*Cursor).Decode(...)
/Users/david/golang/pkg/mod/go.mongodb.org/mongo-driver@v1.0.1/mongo/cursor.go:123
go.mongodb.org/mongo-driver/mongo.(*SingleResult).Decode(0xc00005e440, 0x140ce60, 0x0, 0x0, 0x0)
/Users/david/golang/pkg/mod/go.mongodb.org/mongo-driver@v1.0.1/mongo/single_result.go:59 +0x197
main.main()
/Users/david/tmp/godriver-decode-pointer/main.go:43 +0x426
exit status 2
- backported by
-
GODRIVER-1010 Backport "Decoding SingleResult or cursor to nil pointer type panics"
-
- Closed
-