0

I have configured my nodejs app to use mongodb. I can successfully connect and add data to my mongodb instance. My app is configured as follows (sensitive info is redacted):


// mongoDB configs
const MongoClient = require('mongodb').MongoClient;
const uri = "mongodb+srv://<username>:<password>@codigoinitiative.3klym.mongodb.net/<collection>?retryWrites=true&w=majority";
const client = new MongoClient(uri, { useNewUrlParser: true });

//express configs
const app = express();
const express = require('express');

//mongo endpoint
app.get('/mongo', (req, res) => {
    invoke().then(() => res.send('all good')).catch(err => console.log('invoke error:', err))
});


//mongodb access/logic
async function invoke() {
    console.log('connecting')

    return new Promise((resolve, reject) => {
        client.connect(err => {
            if(err) return reject(err)

            console.log('connected.');
            const collection = client.db("CodigoInitiative").collection("Registered");
            //create document to be inserted
            const pizzaDocument = {
            name: "Pizza",
            shape: "round",
            toppings: [ "Pepperoni", "mozzarella di bufala cheese" ],
            };
        
            // perform actions on the collection object
            const result = collection.insertOne(pizzaDocument);
            console.log(result.insertedCount);
        
            // //close the database connection
            client.close();
        });
    });

}

If I hit the /mongo endpoint, the pizza document is created on the database just fine, but I notice that the connection is never closed; meaning, the /node endpoint never sends the 'all good' string as a response. Also, any subsequent requests to /node then throw the following error:

connecting
the options [servers] is not supported
the options [caseTranslate] is not supported
the options [dbName] is not supported
the options [srvHost] is not supported
the options [credentials] is not supported
connected.
undefined
(node:94679) UnhandledPromiseRejectionWarning: MongoError: topology was destroyed
    at executeWriteOperation (/Users/vismarkjuarez/Documents/GitLab/CodigoInitiative/node_modules/mongodb/lib/core/topologies/replset.js:1183:21)
    at ReplSet.insert (/Users/vismarkjuarez/Documents/GitLab/CodigoInitiative/node_modules/mongodb/lib/core/topologies/replset.js:1252:3)
    at ReplSet.insert (/Users/vismarkjuarez/Documents/GitLab/CodigoInitiative/node_modules/mongodb/lib/topologies/topology_base.js:301:25)
    at insertDocuments (/Users/vismarkjuarez/Documents/GitLab/CodigoInitiative/node_modules/mongodb/lib/operations/common_functions.js:259:19)
    at InsertOneOperation.execute (/Users/vismarkjuarez/Documents/GitLab/CodigoInitiative/node_modules/mongodb/lib/operations/insert_one.js:26:5)
    at executeOperation (/Users/vismarkjuarez/Documents/GitLab/CodigoInitiative/node_modules/mongodb/lib/operations/execute_operation.js:77:17)
    at Collection.insertOne (/Users/vismarkjuarez/Documents/GitLab/CodigoInitiative/node_modules/mongodb/lib/collection.js:517:10)
    at /Users/vismarkjuarez/Documents/GitLab/CodigoInitiative/node.js:154:39
    at /Users/vismarkjuarez/Documents/GitLab/CodigoInitiative/node_modules/mongodb/lib/utils.js:677:5
    at /Users/vismarkjuarez/Documents/GitLab/CodigoInitiative/node_modules/mongodb/lib/mongo_client.js:226:7
(node:94679) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:94679) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

It appears I'm not handling the promise and async call correctly, and am missing a .catch() somewhere, but I'm not sure where. Where am I screwing up here?

2
  • So you want to make a separate DB connection on EVERY request? Commented Feb 5, 2021 at 3:34
  • @codemonkey Good point. That's what I'm doing now -- I plan on refactoring once I get that UnhandledPromiseRejection error sorted out. Commented Feb 5, 2021 at 3:36

1 Answer 1

3

The reason you're not seeing the all good is because this block

return new Promise((resolve, reject) => {

never actually resolves. You should resolve it by calling resolve(...). Only then will your invoke().then(() => ... get triggered.

So I would make that block look something along these lines:

...
...
        
      // perform actions on the collection object
      const result = collection.insertOne(pizzaDocument);
      console.log(result.insertedCount);
        
      // //close the database connection
      client.close();
      resolve('ok')
...
...

But more generally, you certainly want the mongo connection be ready by the time a request comes in instead of opening up a new one every time.

Also, personally, I would simplify your code like so.

//mongo endpoint
app.get('/mongo', invoke);


//mongodb access/logic
const invoke = (req, res) => {
        client.connect(err => {
            if(err) return res.json(err)

            console.log('connected.');
            const collection = client.db("CodigoInitiative").collection("Registered");
            //create document to be inserted
            const pizzaDocument = {
                name: "Pizza",
                shape: "round",
                toppings: [ "Pepperoni", "mozzarella di bufala cheese" ],
            };

            // perform actions on the collection object
            const result = collection.insertOne(pizzaDocument);
            console.log(result.insertedCount);

            // //close the database connection
            client.close();
            res.json({msg: 'all good'})
        });
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.