Trouble Connecting to compose.io mongodb instance with mongoose - node.js

I am using these instructions:
https://help.compose.com/docs/connecting-to-mongodb#mongoose-node-and-compose
This is the connection string they gave me:
MONGO_URI=mongodb://*****:******#aws-us-west-2-portal.1.dblayer.com:15782,aws-us-west-2-portal.0.dblayer.com:15782/mydbname?ssl=true
This is the code I am trying:
certFileBuff = [fs.readFileSync(MONGO_CERT_PATH)]
options = {
mongos: true,
sslCA: certFileBuff,
sslValidate: false,
ssl: true
}
mongoose.connect(MONGO_URI, options)
At this point I get Authentication Failure errors:
if i remove ?ssl=true from the connection string I get the error:
no mongos proxy available
Does anyone have mongoose working with compose.io recently?

If you are not using sharding in mongo set mongos to false.
You can read about sharding in mongo here https://docs.mongodb.com/manual/core/sharded-cluster-query-router/

As it turns out. I had a password that didn't get along with the connection string. I changed the password to something shorter and it worked. fwiw the password that didn't work was: tapasleechframegoldrabbitsauceb88 (Obviously I'm not using anymore)
What I learned:
If you get a mongos proxy error its probably bad config. Make sure ssl=true is set on the connection string and ssl: true in your config.
If you get code: 18 authentication error then the password is either wrong or not formatted properly.
Here is my final working code:
const MONGO_URI = mongodb://****:*****#aws-us-west-2-portal.1.dblayer.com:15782,aws-us-west-2-portal.0.dblayer.com:15782/dbName?ssl=true
let ca, options = {}
if(MONGO_CERT_PATH) {
try {
ca = fs.readFileSync(encodeURI(MONGO_CERT_PATH))
options = {
mongos: {
ssl: true,
sslValidate: true,
sslCA: [ ca ]
}
}
} catch(err) {
logger.warn('mongo ssl cert missing')
}
}
let db = mongoose.connection
db.on('error', (e) => logger.error('connection error:', e))
db.once('open', () => {
logger.info('db connected')
})
mongoose.connect(MONGO_URI, options)

Related

How to fix this MongoClient connection?

I'm trying to connect a node.js app (written in TS) to MongoDB at Yandex Cloud. I have successfully connected there via mongosh:
mongosh "mongodb://<user>:<pass>#<host>:<port>/?replicaSet=<rs>&authSource=<db>&ssl=true" \
--tls --tlsCAFile ./YandexInternalRootCA.crt
where YandexInternalRootCA.crt is the downloaded certificate. Now I'm trying to do the same via MongoClient like this (the code is adapted from their examples; node v15.14.0, mongodb ^4.1.2):
import { MongoClient, Db } from 'mongodb'
import fs from 'fs'
const connnectionString = '<same connection string as the above argument of mongosh>'
const options = {
useNewUrlParser: true,
replSet: {
sslCA: fs.readFileSync('./YandexInternalRootCA.crt')
},
//tlsInsecure: true,
}
const getStorage = async (): Promise<Db> => {
// ts-ignore here is due to some typing problem: once you use 2 arguments
// in .connect, TS shows that it promises void (which is not true)
// #ts-ignore
return (await MongoClient.connect(connnectionString, options)).db()
}
Unexectedly, this results in
MongooseServerSelectionError: self signed certificate in certificate chain
I've tried to add tlsInsecure where it is show commented out (from suggestion for Mongoose), but it doesn't make a difference. What can be the cause and how can I fix this?
PS I've also tried various things like
const getStorage = async (): Promise<Db> => {
return (await MongoClient.connect(config.mongo.connectionUri, {
tls: true,
//sslCA: fs.readFileSync('./YandexInternalRootCA.crt'),
tlsCertificateFile: './YandexInternalRootCA.crt',
tlsInsecure: true,
})).db()
}
which still gives the same result.
If you use mongodb npm package version 4 or higher, you should pass TLS options like this:
const options = {
tls: true,
tlsCAFile: './YandexInternalRootCA.crt'
}

Failed to connect node.js app to MongoDB Atlas despite using the correct connection credentials

I'm trying to connect my node.js application to MongoDB Atlas but I keep getting a "Bad authentication error" and yes, I am using the current database user credentials.
Here is the snippet that's supposed to connect to MongoDB Atlas
const connectDB = async () => {
try {
const conn = await mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false
})
console.log('MongoDB Connected: ' +conn.Connection.host)
}catch (err) {
console.error(err)
process.exit(1)
}
}
My terminate shows me bad authentication and some key-pairs that look so:
{
ok: 0,
code: 8000,
codeName: 'AtlasError',
name: 'MongoError'
}
Any ideas why it is not connecting to MongoDB Atlas?
I finally singled out the problem, it was the MongoDB connection string. I was simply inserting my password in the password field without removing the angle brackets.

Mongodb useUnifiedTopology automatically create a new connection [duplicate]

I am having a kind of strange problem when I trying to establish a single mongodb connection to a db with the mongodb nodejs native driver in the version 3.6.0.
My idea is to have just one connection opened through all the client session and reuse it in the different routes I have in my express server, when I hit it the first time the getDatabase function it creates two connections and after that one of it closes and one stands idle, but when I use a route, the second get opened again (it is like one connection just stays there and do nothing).
I just want to have one connection opened in my pool.
If you see the commented code i was testing with those options but none of them worked for me.
Pd: when I set the socketTimeoutMS to 5000ms just one connection is created but it auto-closes and reopen each 5000ms, which is weird (it reopen itself even when I don't use the connection).
All of this problem happen when I set the useUnifiedTopology to true (I can't set it to false because is deprecated and the other topologies will be removed in the next version of mdb ndjs driver)
Here is an image with the strange behaviour
The code is:
import { MongoClient, Db } from 'mongodb';
import { DB_URI } from '../config/config';
// This mod works as DataBase Singleton
let db: Db;
export const getDataBase = async (id: string) => {
try {
if (db) {
console.log('ALREADY CREATED');
return db;
} else {
console.log('CREATING');
let client: MongoClient = await MongoClient.connect(`${DB_URI}DB_${id}`, {
useUnifiedTopology: true,
/* minPoolSize: 1,
maxPoolSize: 1,
socketTimeoutMS: 180000,
keepAlive: true,
maxIdleTimeMS:10000
useNewUrlParser: true,
keepAlive: true,
w: 'majority',
wtimeout: 5000,
serverSelectionTimeoutMS: 5000,
connectTimeoutMS: 8000,
appname: 'myApp',
*/
});
db = client.db();
return db;
}
} catch (error) {
console.log('DB Connection error', error);
}
};
The driver internally creates one connection per known server for monitoring purposes. This connection is not used for application operations.
Hence, it is expected that you would get two connections established.

Node.js "Error: read ECONNRESET"

I am trying to connect to mongo via Node.js and I'm getting the following error:
connection error: { Error: read ECONNRESET
at exports._errnoException (util.js:1022:11)
at TCP.onread (net.js:610:25) name: 'MongoError', message: 'read ECONNRESET' }
(node:3868) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): MongoError: read ECONNRESET
Here is the code I'm using to connect:
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
module.exports = (config) => {
const fs = require('fs');
let key = fs.readFileSync('../server/test/keys/cert_key.pem');
let ca = [fs.readFileSync('../server/test/keys/ca.pem')];
let o = {
server: {
sslValidate: true,
sslCA: ca,
sslKey: key,
sslCert: key
}
};
mongoose.connect(config.connectionString, o);
let database = mongoose.connection;
database.on('error', console.error.bind(console, 'connection error:'))
database.once('open', (error) => {
if (error) {
console.log(error);
return;
}
console.log('MongoDB ready!')
});
require('./../models/Role').initialize();
require('./../models/User');
require('./../models/Item');
require('./../models/character/Character_item');
require('./../models/Article');
require('./../models/Friend_request');
require('./../models/Code');
require('./../models/Ring');
require('./../models/Ring_shop');
require('./../models/Comment');
};
If I try to connect to mongo from Robo3T, it works. So it seems the problem is in my Node code. Any suggestions?
Accordin mongoDB node driver documentation you must pass ssl: true in the server option in order to connect via SSL otherwise SSL is ignored.
My standard ssl db options is the following :
server: {
ssl: true,
sslValidate:true,
sslCA: ca,
ca: ca,
sslKey: key,
sslCert: key
}
I was having the same issue as I was working on the cloud provided by MongoDB. The reason it was happening with me was that I have configured my home IP to be connected and not my work IP. After adding my work IP in the cloud settings I was able to connect
Confirm that your mongodb database's file is not damaged。If .wt file has damaged, you'll got that error. The .wt filen in your storage path. eg:
storage:
dbPath: E:\Data\mongodb
You can use mongorestore command to repair data if you backuped before. otherwise you can drop the database and re-init a new one.

Mongoose fails to reconnect after replicaset not found error

I'm running a small website that connects to MongoDB Atlas. It has a replicaset with 3 members. For the most part, everything works just fine, but every now an then Atlas' replicaset crashes (or something?) and Mongoose stops working from then on. It throws a single error - MongoError: no primary found in replicaset and that's it.
It doesn't fire mongoose.connection.on('error'), and no errors are reported after this point. It just fails to return any data.
It's sort of hard for me to debug this, as this is running in production, and I have no way of telling when replicaset will fail. Here's how I connect:
function connect() {
tries++;
mongoose.Promise = Promise;
const { uri, options } = config.mongoDb;
return mongoose.connect(uri, options);
}
let db = connect();
db
.connection
.on('error', (err) => {
Raven.captureException(err);
db.disconnect();
})
.on('disconnected', () => {
db = connect();
});
And my options look like this:
options: {
server: {
autoReconnect: true,
ssl: true,
poolSize: 10,
socket_option: {
keepAlive: true
}
}
}
Has anyone had similar problems before? Any idea what I'm doing wrong here, or how to actually catch the error, so I can properly reconnect?

Resources