Search code examples
node.jsmongodbexpressmongoose

Mongoose connection drops at all endpoints


I’ve been working on a project intermittently for some time now. Recently, after transitioning to a new computer, and router none of my endpoints respond

I’ve taken several troubleshooting steps including:

  • Deleting node_modules and reinstalling dependencies with npm.
  • Adjusting inbound and outbound firewall rules for ports 27016.
  • Attempting to app.listen on ports 27016 and 27017 in my application setup.
  • Starting a new project from scratch.
  • Adding extensive console logging for debugging purposes.
  • Successfully connected to MongoDB database using the exact URI via MongoDB Shell and VS Code extensions;
  • the initial connection in my app.js is established, and I can list databases and collections without issue.

However, the mongoose connection to mongodb appears to "drop" unexpectedly when I make requests to my endpoints via postman.

//User.find and User.findOne timeout
router.get('/all', async (req, res) => {
  try {
    // Fetch all users
    const users = await User.findOne({});
    console.log(users);
    // Respond with the list of users
    res.send(users);
  } catch (error) {
    console.error('Error fetching users:', error);
    res.status(500).json({ error: error.message });
  }
});

"error": "Operation users.findOne() buffering timed out after 10000ms"

  router.get('/check-connection', async (req, res) => {
  try {
    console.log('working')
    console.log(mongoose.connection)
    // Ensure the connection is established
    if (mongoose.connection.readyState !== 1) {
      throw new Error('MongoDB connection not established');
    }
    
    // Perform a basic query to the MongoDB server
    const result = await mongoose.connection.useDb.admin().ping();
    console.log('MongoDB Ping Result:', result);
    res.status(200).send('Connection to MongoDB is successful');
  } catch (error) {
    console.error('Error pinging MongoDB:', error);
    res.status(500).json({ error: 'Error connecting to MongoDB: ' + error.message });
  }
});

"error": "Error connecting to MongoDB: MongoDB connection not established" Error pinging MongoDB: Error: MongoDB connection not established

Your insights on resolving this issue would be greatly appreciated. more code below: My app.js https://playcode.io/1945377

my basic router - users.js https://playcode.io/1945378


Solution

  • Wow I guess it has been a while since I have worked on this, and things have changed quite a bit.

    Per: https://mongoosejs.com/docs/connections.html#keepAlive
    If you use multiple connections, you should make sure you export schemas, not models. Exporting a model from a file is called the export model pattern. The export model pattern is limited because you can only use one connection.

    const userSchema = new Schema({ name: String, email: String });
    

    The alternative to the export model pattern is the export schema pattern.

    module.exports = userSchema;
    

    Because if you export a model as shown below, the model will be scoped to Mongoose's default connection.

      module.exports = mongoose.model('User', userSchema);
    

    If you use the export schema pattern, you still need to create models somewhere. There are two common patterns. The first is to create a function that instantiates a new connection and registers all models on that connection. With this pattern, you may also register connections with a dependency injector or another inversion of control (IOC) pattern.

    const mongoose = require('mongoose');
    
    module.exports = function connectionFactory() {
      const conn = mongoose.createConnection(process.env.MONGODB_URI);
    
      conn.model('User', require('../schemas/user'));
      conn.model('PageView', require('../schemas/pageView'));
    
      return conn;
    };
    

    Exporting a function that creates a new connection is the most flexible pattern. However, that pattern can make it tricky to get access to your connection from your route handlers or wherever your business logic is. An alternative pattern is to export a connection and register the models on the connection in the file's top-level scope as follows.

    // connections/index.js
    const mongoose = require('mongoose');
    
    const conn = mongoose.createConnection(process.env.MONGODB_URI);
    conn.model('User', require('../schemas/user'));
    
    module.exports = conn;
    

    in summary it seems like the scope of my connection was limited to where the connection was created because I exported a model not a schema. I don't know specifically what changed that would make this necessary, but it's a semi-simple restructure. hope nobody runs into this, but if so. here's the problem