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

Make executing the same query object twice throw an error #7398

Closed
vkarpov15 opened this issue Jan 6, 2019 · 4 comments
Closed

Make executing the same query object twice throw an error #7398

vkarpov15 opened this issue Jan 6, 2019 · 4 comments

Comments

@vkarpov15
Copy link
Collaborator

This has caused numerous issues, I'll list them out here as I find them:

#5683 (comment)

Here's a couple examples of queries that will execute twice in non-obvious ways. The below examples use findOne(), but you can imagine this being much worse if you use updateOne() with non-idempotent operators.

await MyModel.findOne({}, function(err, res) {});

mySchema.pre('save', function() {
  return MyModel.findOne({}, function(err, res) {});
});

MyModel.findOne({}, function(err, res) {}).exec();

Most of these problems come from mixing callbacks and promises, we may add a warning for that.

For 6.x, we should consider making it so that executing a query multiple times gives you the same result back immediately, unless you clone() the query beforehand.

@vkarpov15 vkarpov15 added the discussion If you have any thoughts or comments on this issue, please share them! label Jan 6, 2019
@vkarpov15 vkarpov15 added this to the 6.0 milestone Jan 6, 2019
@freewil
Copy link
Contributor

freewil commented Nov 21, 2019

Just ran into this issue myself with CoffeeScript. CoffeeScript uses implicit returns, so it can be really easy to accidentally cause multiple query executions by use of a callback, and accidentally returning a mongoose.Query, causing implicit execution of the Query object's then() with promise chaining or use of await.

Here's a more simple example:

// use of callback here will cause execution of query
const query = MyModel.find({}, callback);

// Will cause a duplicate query execution.
// Promise chaining or use of `await` will also
// implicitly call `then()`.
query.then();

@freewil
Copy link
Contributor

freewil commented Nov 21, 2019

CoffeeScript mayhem:

doQuery = (done) ->
  # Use of callback here will cause execution of query.
  #
  # CoffeeScript will implicitly return mongoose.Query object
  MyModel.find({}, done)

Promise.resolve()
  .then ->
      # CoffeeScript will implicitly return mongoose.Query object.
      #
      # Returning mongoose.Query object here in a `then()` callback will 
      # cause implicit call to `then()` on the mongoose.Query object, causing
      # a duplicate query execution.
    doQuery next
  .catch next

@freewil
Copy link
Contributor

freewil commented Nov 25, 2019

For 6.x, we should consider making it so that executing a query multiple times gives you the same result back immediately, unless you clone() the query beforehand.

I agree with this - I also don't think a query object should be returned if you use a callback. If you really still need the query object for some reason you can omit the callback to get the query object and then pass the callback to .exec()

Since Query is a Thenable, it essentially encourages mixing of promises and callbacks.

@vkarpov15
Copy link
Collaborator Author

You're right about coffeescript making this messy. I haven't used coffeescript in a long time so I forgot about this behavior. But then again you'd get a similar issue with ES6 arrow functions. We'll prioritize this change for 6.0. Can't make this change in 5.x because it would be backwards breaking.

@vkarpov15 vkarpov15 added backwards-breaking and removed discussion If you have any thoughts or comments on this issue, please share them! labels Dec 6, 2019
@vkarpov15 vkarpov15 changed the title Make it so that a query can only be executed once Make executing the same query object twice throw an error Mar 22, 2020
vkarpov15 added a commit that referenced this issue Mar 22, 2020
…text: 'query'`

Fix #8395

Also some work to fix tests re: #7398
vkarpov15 added a commit that referenced this issue Mar 22, 2020
@vkarpov15 vkarpov15 added priority Automatically set for Mongoose Pro subscribers and removed priority Automatically set for Mongoose Pro subscribers labels Sep 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants