Why am I getting error "Trying to open unclosed connection."? - node.js

I am trying to connect my node app to mongodb via mongoose. It seems to be working, as I can add documents, but I get the error { [Error: Trying to open unclosed connection.] state: 2 }.
I created a very simple app, just to make sure everything is working properly before connecting my actual app.
Here is my simple app:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var timeSchema = new Schema({ timestamp: String });
var Time = mongoose.model('Time', timeSchema);
mongoose.connect('mongodb://localhost/mydb');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error: '));
db.once('open', function () {
var testA = new Test({ timestamp: Date() });
});
I also tried adding db.close() to the end, but it made no difference.
This is running on a Ubuntu 14.04 VPS with:
Node.js v0.10.3
MongoDB 2.6.3
Mongoose 1.4.21

In my opinion, you are trying to create another connection without closing the current one. So, you might want to use:
createConnection() instead of connect().
In your case, it would look like this:
db = mongoose.createConnection('mongodb://localhost/mydb');

I had the same issue and found that I had the below connection in another file, which was the reason why I couldn't connect with a different database name. The below createConnection is needed:
db = mongoose.createConnection('mongodb://localhost/mydb');
What I had in another file:
db = mongoose.Connection('mongodb://localhost/mydb');

just use mongoose.connect('...'); once.
maybe in your root app.js or index.js file, not in every model or database related files if your are importing (including) them.
Anyways, if you still have doubt you can check it by:
var mongoose = require('mongoose');
var db = mongoose.connection;
db.once('connected', function() {
console.log('mongoDB is connected');
});

shouldn't your
db.once('open', function () {
var testA = new Test({ timestamp: Date() });
});
be
db.once('open', function () {
var testA = new Time({ timestamp: Date() });
});
If "Test" is a different schema based on a different connection, that might affect i think

I had the same issue, but it was due to a typo:
express-sessions instead of express-session

Related

MongooseError: You can not `mongoose.connect()` multiple times while connected

I am getting the below error when trying to connect using moongoose.
MongooseError: You can not mongoose.connect() multiple times while connected.
throw new _mongoose.Error('You can not mongoose.connect() multiple times while connected.');
^
MongooseError: You can not mongoose.connect() multiple times while connected.
at new MongooseError (/node_modules/mongoose/lib/error/mongooseError.js:10:11)
Please help me find the cause for this and how to prevent it
In mongoose version 5.6.1 the check was added https://github.com/Automattic/mongoose/pull/7905
Revert to an older version for a quick fix.
In order to use multiple MongoDB connections use mongoose.createConnection function instead of mongoose.connect.
mongoose.createConnection Will give you a connection object which you can further use in your model file, Cause models are always bound to a single connection
let config = require('../config');
let mongoose = require('mongoose');
exports.connect = function () {
const db = mongoose.createConnection(config.mongoUrl, {
reconnectInterval: 5000,
reconnectTries: 60
// add more config if you need
});
db.on(`error`, console.error.bind(console, `connection error:`));
db.once(`open`, function () {
// we`re connected!
console.log(`MongoDB connected on " ${config.mongoUrl}`);
});
};
I've had the same problem and solved pretty easily.
All i had to do was to remove any connections in my controllers.
Before:
Server.js
const mongoose = require('mongoose');
const connectionString = 'mongodb://localhost:27017/DB';
mongoose.connect(connectionString);
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
//Server code...
Controller.js
const mongoose = require('mongoose');
const connectionString = 'mongodb://localhost:27017/DB';
mongoose.connect(connectionString);
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
//Controller code...
After:
Server.js
const mongoose = require('mongoose');
const connectionString = 'mongodb://localhost:27017/DB';
mongoose.connect(connectionString);
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
//Server code...
Controller.js
//Controller code...
Obviously I removed it from all my controller files.
As pointed out by 'iamdimitar', the ability to call mongoose.connect() more than once was removed in this PR. This is said to be done to prevent errors.
If you must call mongoose.connect() more than once, you can use one mongoose.connect() and use mongoose.createConnection() for the rest. That worked for me (I only used one other mongoose.createConnection())

Node.js - Mongoose not accessing DB in included package

I have started working of late on MEAN technologies;
I have a module myModule. It has routes, services, models accessing database.
I have created another project, myAnotherModule in a separate directory, and have "npm link" ed it into myModule. While I try to use Mongoose in myAnotherModule, it is unable to access DB with proper credentials.
In the following code in myAnotherModule,
var db = mongoose.connection.db;
var mongoDriver = mongoose.mongo;
var gfs = new grid(db, mongoDriver);
it does not find the mongoose.connection.db and db is undefined.
Whereas if I use these lines in myModule, then the code works fine.
Why is myAnotherModule not able to find mongoose.connection.db?
How does npm link work?
Try to connect following way :
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function callback () {
console.log("h");
});
exports.test = function(req,res) {
res.render('test');
};
I happened to encounter this issues recently as well. Typically people separate db config thus cause this problem. Try to declare in proper block that ensures mongodb is already connected.
db.once('open', function callback () {
var gfs = new grid(mongoose.connection.db, mongoDriver);
});

mongoose db.stats() equivalent

I'm using mongoose, and I need to get stats of database.
I know about YourModel.collection.stats(), but thats just for a collection, I need similar thing, but for the database.
Please dont suggest running the shell command. I want to do it using mongoose.
You can call db.stats on the mongoose.connection object:
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
db.db.stats(function(err, stats) {
console.log(stats);
});
});
In addition to MrWhilihog's post, you can also get the data doing the following:
var db = mongoose.connection;
db.db.stats(function (err, stats) {
console.log(stats);
});
This way you are able to get the stats later when your connection is already open.

Node js, require everywhere or add a property to req

The question is about architecture.
I got a module 'db', which establishes connection to mongodb and has a class with schemas, models etc. I export exemplar of that class.
Should i just require('db') in every route file or just do this in one:
server.on('request', function(req) {
req.db = db;
});
db.js:
"use strict";
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
var conn = mongoose.connection;
conn.on('error', console.error.bind(console, 'connection error:'));
conn.once('open', function() {
console.log("Connected to MongoDB.");
});
class db {
constructor() {
//Users
this._usersSchema = mongoose.Schema(
{
username: String,
password: String,
email: String
});
this.Users = mongoose.model("Users", this._usersSchema);
}
}
module.exports = new db();
I think you will find differing opinions, but I prefer to require wherever I need it. modules in node are singletons, so you are always getting the same instance. And I like to separate out my controller logic into their own files away from the routes. Moreover the logic does not expect the complete request and response objects. The reason is I can then use the same code to grab data necessary to serve an API endpoint or render the view server-side without having the mock an entire request and response object.

Nodejs Mongoose Error: getaddrinfo ENOTFOUND undefined undefined:27017

I'm trying to switch to mongoose from using just the native mongodb and having some trouble.
Connecting to the db as I did previously works fine:
var db;
var passDb = function(req, res, next) {
if (!db) {
mongo.connect(process.env.MONGOLAB_URI, function(err, database) {
if (err) throw err;
db = database;
req.db = db;
next();
});
} else {
req.db = db;
next();
}
}
But the way I'm trying to do it now throws an error:
var mongoose = require('mongoose');
var Poll = require('./app/models/poll');
mongoose.connect(process.env.MONGOLAB_URI);
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
// we're connected!
});
The error:
connection error: { [MongoError: getaddrinfo ENOTFOUND undefined undefined:27017
]
name: 'MongoError',
message: 'getaddrinfo ENOTFOUND undefined undefined:27017' }
Any ideas what is causing this?
edit: it works when I use the database uri directly, but not when I use the environment variable. I have checked and triple checked that everything is typed correctly, it refuses to use the environment variable and I have to put it directly in the code :S
Ok, I figured out my mistake, I was connecting to the database before calling require('dotenv').load();. Mystery solved!
mongoose.connect(process.env.MONGOLAB_URI); now works!
adding directConnection=true to connection string worked for me
mongoose.connect("MONGO_URI=mongodb://localhost:27017/test-db?directConnection=true
");
i think you forget to define the env variable
or maybe you forget to call config method of dotenv packages on server or starter file
config it
const dotenv = require("dotenv")
dotenv.config()
on your watched file or starter...
then use process.env.VARIABLE
or for testing you mongo connection use simple string url
like that :
mongodb://localhost:27017/database_name

Resources