[GODRIVER-2359] SingleResult contains error in findOneAndUpdate if upsert is true and no document is found Created: 23/Mar/22  Updated: 27/Oct/23  Resolved: 29/Apr/22

Status: Closed
Project: Go Driver
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Kush Patel Assignee: Preston Vasquez
Resolution: Gone away Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Case:

 Description   

Summary

The SingleResult from collection.findOneAndUpdate({"doesnotexist": "hi"}, {$set: {"hello", "world", {upsert: true})}}  contains a no documents in result error if the find query does not find a document and upsert is true. The document is successfully inserted into the db despite the error. It appears that the error is coming from the driver since upsert returns null unless the returnNewDocument  option is also true in the updateOptions

Please provide the version of the driver. If applicable, please provide the MongoDB server version and topology (standalone, replica set, or sharded cluster).

How to Reproduce

Reproduced in 1.7.3 by calling findOneAndUpdate in the example above

Additional Background

It seems like in this specific scenario, the SingleResult should not contain an error especially since the document was inserted correctly

Slack thread



 Comments   
Comment by PM Bot [ 29/Apr/22 ]

There hasn't been any recent activity on this ticket, so we're resolving it. Thanks for reaching out! Please feel free to comment on this if you're able to provide more information.

Comment by Preston Vasquez [ 14/Apr/22 ]

kush.patel@mongodb.com thank you for reporting!

It seems this behavior is expected when decoding a *SingleResult with no return document, see here.  However, there are at least two idiomatic ways your team can approach handling this.

1. Skip the error

The mongo: no documents in result error is declared and exported by the mongo package and can be used to programmatically "skip" propagation:

if err := sr.Decode(v); err != nil && err != mongo.ErrNoDocuments {
  log.Fatal(err)
}

2. Set the return document

The options package defines a SetReturnDocument that can be used to return documents in a state before or after the operation:

coll := t.Client.Database("test").Collection("coll")
opts := options.FindOneAndUpdate().SetUpsert(true).SetReturnDocument(options.After)
filter := bson.D{{"doesnotexist", "hi"}}
update := bson.D{{"$set", bson.D{{"hello", "world"}}}}
result := coll.FindOneAndUpdate(context.TODO(), filter, update, opts)
var decodedResult interface{}
if err := result.Decode(&decodedResult); err != nil {
	log.Fatal(err)
}
fmt.Println(decodedResult) // [{_id ObjectID("62588daf4d24ebb443c02121")} {doesnotexist hi} {hello world}] 

Generated at Thu Feb 08 08:38:24 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.