Home > Enterprise >  Why I am getting Query was already executed error?
Why I am getting Query was already executed error?

Time:07-15

I have the following Schema and Model:

const userSchema = new mongoose.Schema({
  name: String,
})

const UserModel = mongoose.model('User', userSchema, 'users')

and I have written the following express middleware, which simply takes one argument, awaits that argument, set the returned value from that awaiting job to the req object on a property called gottenDocs, (i.e.: req.gottenDocs)

function getDocumentsMw(query) {
  return async (req, res, next) => {
    const dbRes = await query
    req.gottenDocs = dbRes
    
    next()
  }
}

and I have the following route:

app.get(
  '/users',
  getDocumentsMw(UserModel.find({})), 
  (req, res, next) => {
    const gottenDoc = req.gottenDocs
    res.status(200).json({
      status: 'success',
      data: gottenDoc,
    })
})

That's all I have, now, when I request [ GET " /users " ] I recieve the following response which is great, and nothing is wrong:

{
  "status": "success",
  "data": []
}

but, the weird thing is when I request this route again, it throws this error:

MongooseError: Query was already executed: User.find({})

enter image description here

What could be the problem? is it a bug in Nodejs? which could be hmmm, something like, that it is not removing the function call from the call stack after the response has been sent?

any help appreciated.

CodePudding user response:

The problem is on this line

getDocumentsMw(UserModel.find({})),

Here you create a query once the application start, because of that the query is created once but executed multiple times.

You may need to refactor your code to something like that

getDocumentsMw(() => UserModel.find({})),

Now you are passing a function and not a query. The function creates a query, aka factory. Next step is to refactor getDocumetnsMw to call the function to create a query when it needs to do something with it.

function getDocumentsMw(queryFactory) {
  return async (req, res, next) => {
    const dbRes = await queryFactory()
    req.gottenDocs = dbRes
    
    next()
  }
}

  • Related