How to resolve mongodb pool destroyed error - node.js

I have connected mongodb using mongoose.
const mongoose = require('mongoose');
mongoose.connect(process.env.MONGODB_URI, (err) => {
if (!err) { console.log('MongoDB connection succeeded.'); } else { console.log('Error in MongoDB connection : ' + JSON.stringify(err, undefined, 2)); }
});
After rebooted my system I am facing below the issues.
I am not able to connect mongodb. If i start using mongod command i am getting this error:
***aborting after fassert() failure
2020-07-06T15:31:16.058+0530 F - [WTCheckpointThread] Got signal: 22 (SIGABRT).
mongod.exe ...\src\mongo\util\stacktrace_windows.cpp(246) mongo::printStackTrace+0x43
mongod.exe ...\src\mongo\util\signal_handlers_synchronous.cpp(241) mongo::`anonymous namespace'::abruptQuit+0x81
ucrtbase.dll raise+0x1dd
ucrtbase.dll abort+0x31
mongod.exe ...\src\mongo\util\assert_util.cpp(145) mongo::fassertFailedWithLocation+0xd6
Also i am not able to use anything like find,save ect..mongoose query.If i do anything i am getting below error
MongoError: pool destroyed
at Pool.write (D:\Projects\Angular\project\server\node_modules\mongodb\lib\core\connection\pool.js:840:8)
at _command (D:\Projects\Angular\project\server\node_modules\mongodb\lib\core\wireprotocol\command.js:128:10)
at command (D:\Projects\Angular\project\server\node_modules\mongodb\lib\core\wireprotocol\command.js:28:5)
at Object.query (D:\Projects\Angular\project\server\node_modules\mongodb\lib\core\wireprotocol\query.js:57:3)
at Server.query (D:\Projects\Angular\project\server\node_modules\mongodb\lib\core\topologies\server.js:644:16)
at FindOperation.execute (D:\Projects\Angular\project\server\node_modules\mongodb\lib\operations\find.js:24:12)
at D:\Projects\Angular\project\server\node_modules\mongodb\lib\operations\execute_operation.js:151:17
at Server.selectServer (D:\Projects\Angular\project\server\node_modules\mongodb\lib\core\topologies\server.js:832:3)
at Server.selectServer (D:\Projects\Angular\project\server\node_modules\mongodb\lib\topologies\topology_base.js:342:32)
at executeWithServerSelection (D:\Projects\Angular\project\server\node_modules\mongodb\lib\operations\execute_operation.js:137:12)
at executeOperation (D:\Projects\Angular\project\server\node_modules\mongodb\lib\operations\execute_operation.js:75:7)
at Cursor._initializeCursor (D:\Projects\Angular\project\server\node_modules\mongodb\lib\core\cursor.js:536:7)
at Cursor._initializeCursor (D:\Projects\Angular\project\server\node_modules\mongodb\lib\cursor.js:185:11)
at nextFunction (D:\Projects\Angular\project\server\node_modules\mongodb\lib\core\cursor.js:739:10)
at Cursor._next (D:\Projects\Angular\project\server\node_modules\mongodb\lib\core\cursor.js:202:5)
at fetchDocs (D:\Projects\Angular\project\server\node_modules\mongodb\lib\cursor.js:833:16) {
[Symbol(mongoErrorContextSymbol)]: {}
}
How to resolve the issue?

Related

Knex.js won't connect to postgres

I'm trying to connect to a PostgreSQL database using Knex.js, but I just can't get a connection to happen. The only exception I'm seeing is:
Error KnexTimeoutError: Knex: Timeout acquiring a connection. The pool is probably full. Are you missing a .transacting(trx) call?
I built this simple test script to make sure it wasn't part of our program:
const knex = require("knex")({
client: 'pg',
connection: {
host : 'localhost',
port: 5432,
database: 'postgres',
user: 'postgres',
password: 'password'
},
pool: {
afterCreate: (conn, done) => {
console.log("Pool created");
done(false, conn);
}
},
debug: true,
acquireConnectionTimeout: 2000
});
console.log("A")
const a = knex.raw('select 1+1 as result').then(result => console.log("A Success", result)).catch(err => console.log("A Error", err));
console.log("B")
const b = knex.select("thing").from("testdata").then(data => console.log("B Success", data)).catch(err => console.log("B Error", err));
console.log("C")
const c = knex.transaction(trx => {
trx.select("thing").from("testdata")
.then(data => {
console.log("C Success", data);
})
.catch(err => {
console.log("C Error", err);
});
})
.catch(err => {
console.log("C Error", err);
});
console.log("waiting on query")
// Promise.all([a, b, c]).then(() => {
// console.log("Destroying")
// knex.destroy()
// })
Which is producing the following output
A
B
C
waiting on query
A Error KnexTimeoutError: Knex: Timeout acquiring a connection. The pool is probably full. Are you missing a .transacting(trx) call?
at Client_PG.acquireConnection (E:\DEV\work\niba-backend\node_modules\knex\lib\client.js:347:26)
at runNextTicks (internal/process/task_queues.js:58:5)
at listOnTimeout (internal/timers.js:520:9)
at processTimers (internal/timers.js:494:7) {
sql: 'select 1+1 as result',
bindings: undefined
}
B Error KnexTimeoutError: Knex: Timeout acquiring a connection. The pool is probably full. Are you missing a .transacting(trx) call?
at Client_PG.acquireConnection (E:\DEV\work\niba-backend\node_modules\knex\lib\client.js:347:26) {
sql: undefined,
bindings: undefined
}
C Error KnexTimeoutError: Knex: Timeout acquiring a connection. The pool is probably full. Are you missing a .transacting(trx) call?
at Client_PG.acquireConnection (E:\DEV\work\niba-backend\node_modules\knex\lib\client.js:347:26)
at async Transaction.acquireConnection (E:\DEV\work\niba-backend\node_modules\knex\lib\transaction.js:213:28)
It's never calling the afterCreate method. I have tried it against both our dev database using settings that work for everyone else, and a locally running postgres installation with every combination of settings I could come up with. I even passed this off to another member of the team and it worked fine, so there's something up in my machine, but I have no idea what could be blocking it. I'm not seeing any connection attempts in the postgres logs, and I can't seem to get any better error messages to work off of.
If anyone could come up with things I can try, or ways to get more information out of Knex I would really appreciate it.
I traced the issue down to the verion of the 'pg' package we were using. Was using 7.18 and when I upgraded to the latest version (8.4) it started connecting. No idea why the 7.x version wasn't working.

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.')})
}

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);
});

Problems connecting to MongoDB server from MongoLab

I'm trying to connect to mongodb created by MongoLab, but it always seems to fail.
var mongoose = require('mongoose');
mongoose.connect('mongodb://<dbuser>:<dbpassword>#ds123854.mongolab.com:12345/the_db');
mongoose.connection.on('open', function (ref) {
console.log('Connected to mongo server.');
});
mongoose.connection.on('error', function (err) {
console.log('Could not connect to mongo server!');
console.log(err);
});
// check if mongoose connected; 0 = no; 1 = yes; 2 = connecting; 4 = disconnecting
console.log("mongoose connection: " + mongoose.connection.readyState);
I get the log:
mongoose connection: 2
Could not connect to mongo server!
{ [MongoError: auth failed] name: 'MongoError', ok: 0, errmsg: 'auth failed', code: 18 }
I tried to check the password, so I did the following in my console:
> mongo ds123854.mongolab.com:12345/the_db -u <dbuser> -p <dbpassword>
MongoDB shell version: 3.0.7
connecting to: ds123854.mongolab.com:12345/the_db
rs-ds123854:PRIMARY> db.mynewcollection.insert({ "foo": "bar"})
WriteResult({ "nInserted" : 1 })
rs-ds123854:PRIMARY> db.mynewcollection.find()
{ "_id" : ObjectId("563c1913504f0ab5cb96d74c"), "foo" : "bar" }
The username and password seem right and I can see that the insert command did put something into the database.
I am hosting my server in localhost, so I believe that's the problem. What sort of things am I missing in my configuration?
Solution: Ensure that your version of Mongoose is up to date.
In my case, I was using version 3.6.13, but the current version is 4.2.4
If you specified your mongoose version, just update your package.json file and use command line npm update

Resources