Passing an interface{} to cursor.All results in a panic.
panic: reflect: Elem of invalid type interface {} [recovered] panic: reflect: Elem of invalid type interface {} goroutine 14 [running]: // ... reflect.(*rtype).Elem(0x97e6c0, 0xc00022bae8, 0x194) /usr/lib/go/src/reflect/type.go:912 +0x198 go.mongodb.org/mongo-driver/mongo.(*Cursor).All(0xc0003c1400, 0xb7f340, 0xc000024110, 0x945f80, 0xc00022bae8, 0x0, 0x0) /home/dwrz/.go/pkg/mod/go.mongodb.org/mongo-driver@v1.3.4/mongo/cursor.go:183 +0x15d
It would be great if cursor.All could unwrap the type underlying the interface{}, just like pipeline.All in mgo.
Compare:
https://github.com/mongodb/mongo-go-driver/blob/v1.3.4/mongo/cursor.go#L183
https://github.com/globalsign/mgo/blob/master/session.go#L4436.
For background:
We usually wrap our DB driver in a package. We do this for a few reasons: to set defaults, add logging, and make contributing a little easier for engineers that are not full-time Go / backend engineers.
With mgo, we were able to have Aggregate and Find functions that accepted an interface parameter, and then forwarded that parameter to pipeline.All.
We are unable to do this with the official driver, which seems to be written with the expectation that the type will be passed in directly from the caller.
I'm not a frequent user of reflect, but it seems I can implement the desired functionality by adding the following before line 183 in cursor.go:
if sliceVal.Kind() == reflect.Interface { sliceVal = sliceVal.Elem() } if sliceVal.Kind() != reflect.Slice {}} panic("results argument must be a pointer to a slice"") }
This is pretty much the same code used in mgo's pipeline.All. With this code, my wrapper function is able to decode the passed in interface.