Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DocumentNotFoundError instead of VersionError during save() #10974

Closed
Jonas-Witt opened this issue Nov 15, 2021 · 5 comments
Closed

DocumentNotFoundError instead of VersionError during save() #10974

Jonas-Witt opened this issue Nov 15, 2021 · 5 comments
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it.
Milestone

Comments

@Jonas-Witt
Copy link

Jonas-Witt commented Nov 15, 2021

Do you want to request a feature or report a bug?
Bug

What is the current behavior?
Model.save() can throw DocumentNotFoundError although the document exists and only differs in the expected __v. According to my understanding this should yield a VersionError instead. When enabling debug mode, I see one weird query that seems to trigger the DocumentNotFoundError:

Mongoose: robots.findOne({ _id: new ObjectId("61925c11b38b4700cbd4ca48"), __v: 57 }, { session: null, projection: { _id: 1 } })

However, in the resulting exception, __v is not mentioned:

DocumentNotFoundError: No document found for query "{ _id: new ObjectId("61925bcdc8b551b0655f8fb8") }" on model "Robot"
    at /home/jonas/workspace/cartken_catkin/src/web/node_modules/mongoose/lib/model.js:349:19
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

Usually, I'd just expect an updateOne but no findOne call during .save().

If the current behavior is a bug, please provide the steps to reproduce.

const robotSchema = new Schema({ name: String }, { optimisticConcurrency: true });
const Robot = mongoose.model('Test', robotSchema);
...

const robot = await Robot.findOne({_id: someId}).orFail().exec();
robot.name = 'something';
await robot.save();

The error is thrown sporadically. To trigger the error I believe a competing modification to the document is needed so that there is a version mismatch when saving.

What is the expected behavior?
robot.save() should either succeed or throw a VersionError if a competing modification took place. However, sometimes I see a DocumentNotFoundError instead, although the document exists and subsequent queries for the same document succeed.

What are the versions of Node.js, Mongoose and MongoDB you are using?
NodeJS: 16.13.0
Mongoose: 6.0.12
MongoDB: 4.4.10

@IslandRhythms IslandRhythms added the help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary label Nov 15, 2021
@IslandRhythms
Copy link
Collaborator

So I am sort of able to reproduce this issue. It seems to be more of an issue where the document is not yet in the the model when the save is called. Can you show that the document is in the database when the error is being thrown?

@Jonas-Witt
Copy link
Author

I am sure that the document is in the database, as before and after there are successful calls with the same document id:

  console.info
    Mongoose: robots.findOne({ _id: new ObjectId("61936bc2417fa977b46c3c2e") }, { projection: {} })

      at NativeCollection.Object.<anonymous>.NativeCollection.$print (../node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:264:11)

  console.info
    Mongoose: robots.updateOne({ _id: new ObjectId("61936bc2417fa977b46c3c2e"), __v: 68 }, { '$set': { 'scheduledStops.0.estimatedWaitingDuration': 2.002, updatedAt: new Date("Tue, 16 Nov 2021 08:28:59 GMT") }, '$inc': { __v: 1 }}, { session: null })

      at NativeCollection.Object.<anonymous>.NativeCollection.$print (../node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:264:11)

  console.info
    Mongoose: robots.findOne({ _id: new ObjectId("61936bc2417fa977b46c3c2e"), __v: 68 }, { session: null, projection: { _id: 1 } })

      at NativeCollection.Object.<anonymous>.NativeCollection.$print (../node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:264:11)

  console.warn
    Got DocumentNotFoundError instead of VersionError

  console.info
    Mongoose: robots.findOne({ _id: new ObjectId("61936bc2417fa977b46c3c2e") }, { projection: {} })

      at NativeCollection.Object.<anonymous>.NativeCollection.$print (../node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:264:11)

  console.info
    Mongoose: robots.findOne({ _id: new ObjectId("61936bc2417fa977b46c3c2e"), __v: 69 }, { session: null, projection: { _id: 1 } })

      at NativeCollection.Object.<anonymous>.NativeCollection.$print (../node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:264:11)

Maybe one key hint is that I am running the save() and actually just writing the same data, so that no updateOne is triggered by the change detection. I only see these findOne instead of where usually I'd see an updateOne in the calls that fail with the DocumentNotFoundError:

robots.findOne({ _id: new ObjectId("61936bc2417fa977b46c3c2e"), __v: 68 }, { session: null, projection: { _id: 1 } })

@IslandRhythms
Copy link
Collaborator

After rereading your issue, It appears your initial assumption about the cause of the problem is correct.

To trigger the error I believe a competing modification to the document is needed so that there is a version mismatch when saving.

That is the only way i am able to get it to pop up exactly as stated.

The script

const mongoose = require('mongoose');
mongoose.set('debug', true)

const robotSchema = new mongoose.Schema({
    name: String
}, {optimisticConcurrency: true });

const Robot = new mongoose.model('Robot', robotSchema);

async function run() {
    await mongoose.connect('mongodb://localhost:27017/', {useNewUrlParser: true,
    useUnifiedTopology: true,});
    await mongoose.connection.dropDatabase();
    const entry = await Robot.create({name: 'WallE'});
    const changes = await Robot.findOne({_id: entry._id}).orFail().exec();
    const other = await Robot.findOne({_id: entry._id}).orFail().exec();
    changes.name = 'John';
    await changes.save();
    other.name = 'WallE';
    await other.save();
}

run();

@IslandRhythms IslandRhythms added confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. and removed help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary labels Nov 16, 2021
@vkarpov15 vkarpov15 added this to the 6.0.14 milestone Nov 17, 2021
@Jonas-Witt
Copy link
Author

Thanks for your quick responses!

@vkarpov15
Copy link
Collaborator

This occurs when the underlying document that Mongoose is trying to save isn't found, likely because the document was deleted. In v6.0.14 that will throw a VersionError rather than a DocumentNotFoundError.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it.
Projects
None yet
Development

No branches or pull requests

3 participants