0
function uploadVote(voter, vote){
MongoClient.connect(url, function(err, db){
    if (err) throw err;

    db.collection('testvote', function(err, collection) {
        collection.find({"psid": voter}).toArray(function(err, result) {
            if(!result[0]){
                db.collection("testvote").insert({psid: "a", choice:0}, function(err, res) {
                    if (err) throw err;

                    console.log('insertone')
                    sendTextMessage(". ")
                });
            } else if(!result[0].choice){
                db.collection("testvote").update({psid: voter}, {$set: {'choice': vote}}, function(err, res){
                    if (err) throw err; 
                    sendTextMessage(". ")
                })
            } else{
                sendTextMessage(voter, "!");
            }

        });
        db.close(); 
    });
})
}

Hi, I'm developing a facebook messenger that let users vote something. In the code above, I see no syntax error at all. But when this function is executed it keeps making a error:

/app/node_modules/mongodb/lib/utils.js:123
2017-05-18T12:09:19.856188+00:00 app[web.1]:     process.nextTick(function() { throw err; });
2017-05-18T12:09:19.856188+00:00 app[web.1]:                                   ^
2017-05-18T12:09:19.858765+00:00 app[web.1]:     at ReplSet.insert (/app/node_modules/mongodb/lib/replset.js:398:18)
2017-05-18T12:09:19.858761+00:00 app[web.1]: MongoError: topology was destroyed
2017-05-18T12:09:19.858764+00:00 app[web.1]:     at ReplSet.insert (/app/node_modules/mongodb-core/lib/topologies/replset.js:1025:47)
2017-05-18T12:09:19.858766+00:00 app[web.1]:     at executeCommands (/app/node_modules/mongodb/lib/bulk/ordered.js:455:23)
2017-05-18T12:09:19.858766+00:00 app[web.1]:     at OrderedBulkOperation.execute (/app/node_modules/mongodb/lib/bulk/ordered.js:508:10)
2017-05-18T12:09:19.858767+00:00 app[web.1]:     at bulkWrite (/app/node_modules/mongodb/lib/collection.js:664:8)
2017-05-18T12:09:19.858768+00:00 app[web.1]:     at Collection.insertMany (/app/node_modules/mongodb/lib/collection.js:534:44)
2017-05-18T12:09:19.858769+00:00 app[web.1]:     at /app/index.js:121:41
2017-05-18T12:09:19.858768+00:00 app[web.1]:     at Collection.insert (/app/node_modules/mongodb/lib/collection.js:836:15)
2017-05-18T12:09:19.858770+00:00 app[web.1]:     at handleCallback (/app/node_modules/mongodb/lib/utils.js:120:56)
2017-05-18T12:09:19.858771+00:00 app[web.1]:     at /app/node_modules/mongodb/lib/cursor.js:860:16

Please help me to solve this.

brain_team
  • 31
  • 8
  • 1
    Possible duplicate of [mongoError: Topology was destroyed](http://stackoverflow.com/questions/30909492/mongoerror-topology-was-destroyed) – George May 18 '17 at 12:16
  • 1
    I think your `db.close()` call might be run before the callback that gets passed to your `collection.find()` call. This would mean that by the time the subsequent `insert()` or `update()` calls get made, the database connection has been closed – Devman May 18 '17 at 12:28
  • Thanks for your help! Then how I should I edit my codes? – brain_team May 18 '17 at 12:31
  • just put your db.close() inside your callback – schaffioverflow May 18 '17 at 12:31
  • 1
    You need to make sure that `db.close()` only gets called after you are done with it. You could either just put it at the end of each code branch (i.e. after each case of `sendTextMessage()`) or wrap the whole thing in a promise and call resolve in those locations instead. I'll write an answer below. – Devman May 18 '17 at 12:33
  • Thanks you so much....I will be waiting for your answer. Thank you again!!! – brain_team May 18 '17 at 12:37

2 Answers2

1

The database calls will be asynchronous meaning that the db.close() line will be run before the code inside the callbacks.

You need to make sure that db.close() only gets called after you are done with the connection. You could either just put it at the end of each code branch (i.e. after each case of sendTextMessage()) or wrap the whole thing in a promise and call resolve in those locations instead.

Here is a version of your code wrapped in a promise. The resolve() method is only called when you know there are no more requests to be made. You could also not wrap it in a promise and place a db.close() statement in each place that I have put a resolve() statement.

function uploadVote(voter, vote){
  MongoClient.connect(url, function(err, db){
      if (err) throw err;

      new Promise((resolve, reject) => {
          db.collection('testvote', function(err, collection) {
              collection.find({"psid": voter}).toArray(function(err, result) {
                  if(!result[0]){
                      db.collection("testvote").insert({psid: "a", choice:0}, function(err, res) {
                          if (err) throw err;

                          console.log('insertone')
                          sendTextMessage(". ")
                          resolve();
                      });
                  } else if(!result[0].choice){
                      db.collection("testvote").update({psid: voter}, {$set: {'choice': vote}}, function(err, res){
                          if (err) throw err; 
                          sendTextMessage(". ")
                          resolve();
                      })
                  } else{
                      sendTextMessage(voter, "!");
                      resolve();
                  }

              });
          });
      }).then(() => db.close());
  })
}
Devman
  • 310
  • 2
  • 10
  • 1
    np. also, I just thought you might want to change the `.then(() => db.close())` to `.finally(() => db.close())` and change the throw statements to `reject(err)`. That should make sure that the connection gets closed even if you error out. `.finally` gets run regardless of whether the promise resolves or rejects. – Devman May 18 '17 at 13:06
0

If you're getting a MongoError: topology was destroyed like that, it means your connection to the MongoDB server has been interrupted. Make sure you have a good connection and it's running when you run your query.

Paul
  • 35,689
  • 11
  • 93
  • 122
  • Oh, thanks. I'm using MongoDB Atlas and maybe there is a problem with that. Can I have a advice again after I try once more? I appreciate your help so much by the way. – brain_team May 18 '17 at 12:21