NodeJS Mongoose & Mongo Db Connection Issue - node.js

I am new to mongodb and I have setup on mac os and it's successfully done. Now when I run my node js application with mongoose to connect with mongodb, It's always show a connecting state.
I am using below code to connect the database.
module.exports = function() {
/**
* Requiring this module will populate the mongoose connection pool.
* Any models defined on mongoose will be ready to use (mongoose is
* a singleton).
*/
var mongoose = require('mongoose');
var logger = include('logger.js');
// attempt to connect to the database server
logger.info("DB CONNECTION ", {DB: global.settings.DB, options: global.settings.DbOptions});
//console.log("DB CONNECTION ", {DB: global.settings.DB, options: global.settings.DbOptions});
mongoose.connect('mongodb://localhost/circleweb');
mongoose.connection.on("open", function(ref) {
console.log("Connected to mongo server.");
});
mongoose.connection.on('connected', function () {
console.log('connected');
console.log('Mongoose default connection open to ' + global.settings.DB);
});
mongoose.connection.on('error', function (error) {
logger.error(error);
console.log('Mongoose default connection error: ' + error.err);
// if the database cannot be connected to. We are going to throw
// an error. This will be caught by the error handler
throw error.err;
});
mongoose.connection.on('disconnected', function () {
console.log('Mongoose default connection disconnected');
});
process.on('SIGINT', function () {
mongoose.connection.close(function () {
console.log('Mongoose default connection disconnected through app termination');
process.exit(0);
});
});
console.log(mongoose.connection.readyState);
return mongoose.connection;
}();
And When i run my application I am not getting any callback from mongoose not even any error.
Also when I run mongod on terminal it shows correct output and also it's accepting the connection from nodejs application but not connecting with it.
Any help would be appreciate

Because console.log(mongoose.connection.readyState) is running synchronously - it will get executed first - before the mongoose.connection.on async calls, which means that the state is 2 or connecting.
Surround it with a timeout and you will get the expected 1 value:
setTimeout( () => {
console.log(mongoose.connection.readyState); // prints 1
}, 2000);
Or print the state within the async call:
mongoose.connection.on('connected', function () {
console.log(`STATE: `, mongoose.connection.readyState);
console.log('connected');
console.log('Mongoose default connection open to ' );
});

Related

MongoDB/Mongoose unhandled error on disconnect - why isn't it firing on('error') event?

I'm connecting to a MongoDB database using the mongoose library.
After running mongoose.connect() I'm creating a mongoose.connection.on('error') handler.
After the app starts, I stop the MongoDB service to simulate a 'lost-connection event'. The script outputs:
events.js:196
throw er; // Unhandled 'error' event
...
and my app crashes.
The on('error') handler never executes. Why not? Isn't that the point of this event handler: to handle errors that the MongoDB connection throws, to avoid the app crashing?
Expected behavior: if the MongoDB connection is lost, the app attempts to reconnect indefinitely.
What am I doing wrong?
Here's my full connection code:
function dbConnect() {
// Establish MongoDB connection
logger.debug(`Connecting to MongoDB database ${process.env.DB_SERVER}:${process.env.DB_PORT} database ${process.env.DB_DATABASE}...`)
// Set up connection string
const db_uri = `mongodb://${process.env.DB_USER}:${process.env.DB_PASS}#${process.env.DB_SERVER}:${process.env.DB_PORT}/${process.env.DB_AUTH_DATABASE}`
// Initiate connection:
mongoose.connect(db_uri, {
dbName: process.env.DB_DATABASE, // Connect to the specified database
useNewUrlParser: true, // Use new settings
useUnifiedTopology: true,
useCreateIndex: true,
autoIndex: process.env.DB_AUTO_INDEX, // Autoindex
reconnectTries: Number.MAX_VALUE, // Keep retrying forever (thanks https://stackoverflow.com/a/39684734/1502289 and https://stackoverflow.com/a/41923785/1502289)
reconnectInterval: 5000, // Time to wait between reconnection attempts
})
.then(() => {
logger.debug("MongoDB successful connection")
})
.catch((err) => {
logger.debug("MongoDB connection error", err)
})
const db = mongoose.connection
// Set up database event handlers:
db.on('error', function(err) { logger.error("Unable to connect to database. Error: " + err) } )
db.once('open', function() {
logger.debug('Mongoose database connection established.')
// Load common properties from database:
// ... [snip]
})
db.on('disconnected', function() {
logger.error('MongoDB disconnected. Attempting to reconnect...')
})
db.on('reconnected', function() { logger.debug('Mongoose reconnected.')})
}

mongoose createConnection not start and no errors

I maked multiple db app. All worked correctly when I connected my code to db. But now... My app connecting to the port, but db connection not fired. Thats mean that all my connections stay on readyState = 2. No errors, no connections. I checked other files about 500 times - there is no other connections. My connection code:
const connectionOptions = {
useNewUrlParser: true,
auto_reconnect: true,
socketTimeoutMS: 0,
keepAlive: true,
reconnectTries: 30,
}
mongoose.Promise = global.Promise;
mongoose.main_conn = mongoose.createConnection(config.db.url, connectionOptions);
mongoose.hist_conn = mongoose.createConnection(config.db.hist, connectionOptions);
mongoose.main_conn.on("connected", function(){
console.log("Mongoose connected to " + config.db.url);
});
mongoose.main_conn.on("error", function(err){
console.log("Mongoose connection error" + err);
});
The error was stupid. But maybe my answer will be some helpful for others. In one file of the application I used javascript's sleep, when setTimeout called in Promise. And I maked an error inside it:
function sleep (ms) {
return new Promise(resolve => setTimeout(resolve(), ms));
}
As you see, I maked endless loop. It called before connection was done, and freezed my app. After I fixed this error the app work's correctly:
function sleep (ms) {
return new Promise(resolve => setTimeout(() => resolve(), ms));
}

When mongodb server is down how to catch the error while running mongoose query

I am using mongoose for connecting node.js with mongoDB, now i wrote below query
var trans = new transmodel({method: method, trans_id: r});
trans.save(function(err) {
if (err) {
console.error("Razor_pay_webhook Error 4 err: " + err);
res.write('statusCode: 200');
res.end();
} else {
res.write('statusCode: 400');
res.end();
}
});
I thought when my mongodb cluster will be down then i will get 'err' while executing above mongoose query, but when i ran above query while my mongo cluster was down nothing happened(No err was called). Can anyone please tell me how can i catch the error if my mongodb server is down inside my query. Also for reconnecting again with my cluster i have set below parameters but my node server is not trying to reconnect again with my mongodb server i don't know what's going wrong.
var mongoose = require('mongoose');
var config = require('./config/database.js');
var DB_URL = config.db.url;
mongoose.connection.on("connected", function(ref) {
console.log("Connected to " + " DB!");
});
mongoose.connection.on("error", function(err) {
console.error('Failed to connect to DB ' + ' on startup ', err);
if (err) {
return next(err);
}
});
mongoose.connection.on('disconnected', function(err) {
console.log('Mongoose default connection to DB :' + ' disconnected');
if (err) {
return next(err);
}
});
var gracefulExit = function() {
mongoose.connection.close(function () {
console.log('Mongoose default connection with DB :' + ' is disconnected through app termination');
process.exit(0);
});
}
process.on('SIGINT', gracefulExit).on('SIGTERM', gracefulExit);
exports.con_close = function () {
console.log('Mongoose connection disconnected');
mongoose.connection.close();
}
var options = {
server: {
socketOptions: {
keepAlive: 1000,
connectTimeoutMS: 30000
}
},
replset: {
rs_name: 'replicaset',
auto_reconnect:true,
socketOptions: {
keepAlive: 1000, // doubt about it
connectTimeoutMS: 30000
}
},
user: 'root',
pass: 'G3saGT2Y',
auth: {
authdb: 'admin'
}
}
mongoose.connect(DB_URL, options, function(err) {
console.log('ho rha hai');
if (err) {
console.log('error connection to mongo server!');
console.log(err);
}
});
You are using mongoose, it emits events (the EventEmitter pattern) when the database is down and when the database is reconnecting and up again.
from mongoose code found here we can see that the library db connection - connection.js
has the following events that are emitted:
* #param {Mongoose} base a mongoose instance
* #inherits NodeJS EventEmitter
http://nodejs.org/api/events.html#events_class_events_eventemitter
* #event connecting: Emitted when connection.{open,openSet}() is executed on this connection.
#event connected: Emitted when this connection successfully connects to the db. May be emitted multiple times in reconnected scenarios.
#event open: Emitted after we connected and onOpen is executed on all of this connections models.
#event disconnecting: Emitted when connection.close() was executed.
#event disconnected: Emitted after getting disconnected from the db.
#event close: Emitted after we disconnected and onClose executed on all of this connections models.
#event reconnected: Emitted after we connected and subsequently disconnected, followed by successfully another successfull connection.
#event error: Emitted when an error occurs on this connection.
#event fullsetup: Emitted in a replica-set scenario, when primary and at
least one seconaries specified in the connection string are connected.
#event all: Emitted in a replica-set scenario, when all nodes specified in the connection string are connected.
When the database is down you will receive two events:
1. disconnected
2. error (the error that driver encountered)
When the database is up again you will receive the reconnect event.
So you don't need to try catch the error rather you should listen to these events.
More helpful information about connection failures and reconnecting can be found here.
This article explain how to use and configure the autoReconnect and the bufferMaxEntries according to your settings.

how to catch Sequelize connection error

How to catch a sequelize connection error in case there is one?
I tried to do
var connection = new Sequelize("db://uri");
connection.on("error", function() { /* perhaps reconnect here */ });
but apparently this is not supported.
I wanted to do this because I think sequelize might be throwing an occasional unhandled ETIMEOUT and crashing my node process.
Currently I am using sequelize to connect a mysql instance. I only need it for like 2-3 hours and during that time I will be doing a many read queries. The mysql server will not be connected to anything else during that time.
Using sync() for this is considerably dangerous when using external migrations or when database integrity is paramount (when isn't it!)
The more up-to-date way of doing this is to use authenticate()
sequelize
.authenticate()
.then(() => {
console.log('Connection has been established successfully.');
})
.catch(err => {
console.error('Unable to connect to the database:', err);
});
Using sequelize sync method provides an easy way to catch the error.
The then block handles a Successful connection and the catch handles the rejection.To get a detailed reason for a failure access the error object.
example: error.message e.t.c
Hope this helps.
sequelize.sync().
then(function() {
console.log('DB connection sucessful.');
}).catch(err=> console.log('error has occured'));
Use sequelize sync for that
var Sequelize = require('sequelize');
sequelize = new Sequelize(config.database, config.username, config.password, {
'host' : config.host,
'dialect' : config.dialect,
'port' : config.port,
'logging' : false
})
sequelize.sync().then(function(){
console.log('DB connection sucessful.');
}, function(err){
// catch error here
console.log(err);
});

Connecting to redis using kue always creates a connection to localhost

I can't connect to Redis using kue, I've followed this article, practically I'm creating the connection by using the kue redis client, and the connection code is this:
var kue = require('kue'),
redis = require('kue/node_modules/redis');
app.redisClient = redis.createClient('6379', 'remoteip',{});
app.redisClient.on('error', function (err) {
console.log('Redis error encountered', err);
});
app.redisClient.on('end', function() {
console.log('Redis connection closed');
});
kue.redis.createClient = function() {
console.log('client ------------------',app.redisClient);
return app.redisClient;
};
and it seems like Kue is trying to connect to a local Redis (which I don't have installed), because I'm getting this exception:
Error: Redis connection to 127.0.0.1:6379 failed - connect
ECONNREFUSED
I've read this post and it seems like the issue has been resolved in version 0.8 and I'm using 0.8.11 :/, finally I also wanted to override the client using a different client instance by using redis nodejs without any luck, because I'm getting the same error.
any help will be more than appreciated.
thanks!
I used a different way to setup the connection and it works so far this is what I've done:
app.redisClient = redis.createClient(config.redisPort, config.redisUrl,{});
app.redisClient.on('connect', function () {
console.info('successful connection to redis server');
});
app.redisClient.on('error', function (err) {
console.log('Redis error encountered', err);
});
app.redisClient.on('end', function() {
console.log('Redis connection closed');
});
kue.app.listen(config.kuePort);
app.jobs = kue.createQueue({
redis: {
createClientFactory: function(){
return app.redisClient;
}
}
});

Resources