MongoError: connection destroyed, not possible to instantiate cursor

Viewed 5521

While running an app on Heroku, using Parse-Server with mLab, I am getting the following error in the logs:

app[web.1]: /app/node_modules/parse-server/lib/ParseServer.js:481
app[web.1]:             throw err;
app[web.1]:             ^
app[web.1]: MongoError: connection destroyed, not possible to instantiate cursor
app[web.1]:     at nextFunction (/app/node_modules/mongodb-core/lib/cursor.js:607:55)
app[web.1]:     at Cursor.next [as _next] (/app/node_modules/mongodb-core/lib/cursor.js:692:3)
app[web.1]:     at fetchDocs (/app/node_modules/mongodb/lib/cursor.js:856:10)

To make things even more complicated, I do not get it all the time, while the same code is running.

After searching on the web I read that it happens when trying to read more than 100 records from the database. This seems consistent with what I am observing.

Unfortunately I did not find any solution to the problem on the web. Therefore my question: How can I handle this issue?

Is there any way to raise the threshold from 100 to a higher value? Or any other good way to deal with this problem?

In case this may be useful here the code for the function doing the job. It works like charm in most cases. When the typKey provided happens to match too many records, I get the problem above mentioned.

function get_List(displayPage, db, response) {
  db.collection('TheCollection', function (err, collection) {
    collection.find({"typeKey": "TYPE01"}).toArray(function(err, items) {
      if(err) throw err;

      response.render('pages/displayList.ejs', {
        dataArray: items
      });
    });
  });
}
2 Answers

You need to make sure that you call your close() after the cursor has been full emptied. You can do that by making sure you use async/await or promises, .then() so that the response has a chance to be fully written out before you close the mongo collection

Putting in a delay to make sure the cursor has been fully completed, is very crude and likely to give you weird bugs down the road.

If you have access to async/await, make the get_list() function async and make sure you await it's response before you close the connection. Otherwise, wrap it in a Promise, and only close the connection when the promise is resolved. e.g.

function get_List(displayPage, db, response) {
  db.collection('TheCollection', function (err, collection) {
    collection.find({"typeKey": "TYPE01"}).toArray(function(err, items) {
      if(err) throw err;

      response.render('pages/displayList.ejs', {
        dataArray: items
      });
    });
  });
}

async function whichCallsget_List(request response) => {
  try {
    var client = await MongoClient.connect(
                        mongourl,
                       { useNewUrlParser: true }
                 )
    const db = await client.db(process.env.DB_NAME)

    await get_List('displayPage', db, response)
    db.close();
  } catch (reason) {
    // error handling
  }
}

For example -In my case- I Closed the connection before return

var readByCondition = function (connectionString, dbName, collectionName, condition, params, callback) {
    try {
        var db = mongo.db(connectionString + dbName, {
            native_parser: false
        });

        db.bind(collectionName);

        db.collection(collectionName).find(condition, params).toArray(function (err, result) {
            if (err) {
                db.close();
                return callback(err, result);
            }
            db.close();
            return callback(err, result);

        });

    } catch (err) {
        throw err;

    }
}
Related