Error: read EINVAL when connecting to MongoDB with mongoose and SSL - node.js

When I try to connect to my MongoDB that requires SSL, my NodeJs app crashes on the following method:
conn = await mongoose.connect(process.env.DB_HOST, {
tlsCAFile: __dirname + '/ca-certificate.crt',
useNewUrlParser: true,
useUnifiedTopology: true
})
and I get the following error in stderr.log:
events.js:377
throw er; // Unhandled 'error' event
^
Error: read EINVAL
at Pipe.onStreamRead (internal/stream_base_commons.js:209:20)
Emitted 'error' event on Socket instance at:
at emitErrorNT (internal/streams/destroy.js:106:8)
at emitErrorCloseNT (internal/streams/destroy.js:74:3)
at processTicksAndRejections (internal/process/task_queues.js:82:21) {
errno: -22,
code: 'EINVAL',
syscall: 'read'
}
The interesting this is that this works just fine on my local windows machine, but crashes when deployed to A2Hosting shared hosting.
Also I am able to connect successfully (even on A2hosting) when connecting without mongoose like so:
const client = new MongoClient(uri);
try {
await client.connect();
const db = client.db('egomenu');
console.log('connected successfully');
} finally {
await client.close();
}
I am using mongoose: ^6.3.1 and node: 14.20.1 on A2hosting.
I believe that the error is generated when trying to read the .crt file during connection; however cannot figure out what is causing it.
Any help would be greatly appreciated :)

Related

How to Use Node SMPP to Connect to InetLab SMPP Server

I am trying to build an SMS an SMS Client using NodeJS which should connect to ``Inetlab ```` SMPP Server to send Short messages. I downloaded Inetlab SMPP client and Server and run them both. When I try to connect and send an SMS from the client via port 7777 (Not that it matters), The connection is bound successfully and the message is sent across.
My problem is when I try connect to the same local SMPP server via a client that I have bult with NodeJS using the node-smpp library, the connection fails even though I am using the same localhost and port 7777.
Below is my connection code:
module.exports = class{
constructor(){
this.session = null
this.smppConfig = {
url:"smpp://localhost:7777",
auto_enquire_link_period:10000,
debug:true
}
}
StartSmppSession= ()=>{
return new Promise( async(resolve, reject)=>{
try{
console.log(this.smppConfig)
this.session = smpp.connect(this.smppConfig,()=>{
this.session.bind_transceiver({
system_id:process.env.SMPP_SYSTEM_ID,
password:process.env.SMPP_PASSWORD
},(pdu)=>{
if(pdu.command_status === 0){
resolve({message:"Connection bound successfully!"})
}else{
reject({message:"Failed to bind!",pdu})
}
})
})
}catch(err){
//reject(err.message)
}
})
}
sendSMS = (payload)=>{
return new Promise(async (resolve, reject)=>{
try{
//payload = {destination_addr:"phone_number", "short_message":"The message here"}
this.session.submit_sm(payload, async (pdu)=>{
pdu.command_status === 0 ? resolve("Message successfully sent!") : reject("Failed to send SMS!")
})
}catch(err){
reject(err.message)
}
})
}
}
When I invoke the StartSmppSession() function in my controller, I get the following error log:
2022-12-06T09:30:40.973Z - cli - 315644 - socket.error - connect ECONNREFUSED ::1:7777 - {"errno":-4078,"code":"ECONNREFUSED","syscall":"connect","address":"::1","port":7777}
node:events:491
throw er; // Unhandled 'error' event
^
Error: connect ECONNREFUSED ::1:7777
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1284:16)
Emitted 'error' event on Session instance at:
at Socket.<anonymous> (C:\Users\c.mwale\Desktop\NRB API Test\Notifications Module\SMSGateway\src\SMS_Outgoing\node_modules\smpp\lib\smpp.js:119:8)
at Socket.emit (node:events:513:28)
at emitErrorNT (node:internal/streams/destroy:151:8)
at emitErrorCloseNT (node:internal/streams/destroy:116:3)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
errno: -4078,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '::1',
port: 7777
}
I understand that there is a SMPP library for .NET documented on the inetlab website, but I am of the view this the intent of using a C# example was not to dictate the framework nor language of implementation.

Retry connection postgres Nodejs

I am using a postgres database for my express web server.
I am using the 'pg' library to execute queries on this database.
Here is my connection method :
const db = new Client({
user: 'xxx',
host: 'xxx',
database: 'xxx',
password: 'xxx',
port: xxx,
})
db.connect(err => {
if (err) {
console.error('connection error', err.stack)
} else {
console.log('connected')
}
Then to execute a request I do this:
db.query(MY_REQUEST, function (err, data) {
if (err) throw err;
res.render('hello/world', {
title: 'Hello',
data: data.rows
});
});`
It all works perfectly. But after several minutes without using my website, my connection to the db times out, and I get the following error:
node:events:355
throw er; // Unhandled 'error' event
^
Error: Connection terminated unexpectedly
at Connection.<anonymous> (/usr/src/app/node_modules/pg/lib/client.js:132:73)
at Object.onceWrapper (node:events:484:28)
at Connection.emit (node:events:378:20)
at Socket.<anonymous> (/usr/src/app/node_modules/pg/lib/connection.js:58:12)
at Socket.emit (node:events:378:20)
at TCP.<anonymous> (node:net:665:12)
Emitted 'error' event on Client instance at:
at Client._handleErrorEvent (/usr/src/app/node_modules/pg/lib/client.js:319:10)
at Connection.<anonymous> (/usr/src/app/node_modules/pg/lib/client.js:149:16)
at Object.onceWrapper (node:events:484:28)
[... lines matching original stack trace ...]
at TCP.<anonymous> (node:net:665:12)
How could I do to reconnect automatically when the connection is cut or when a request fails?
You should attach an error-handler in order to prevent the unhandled error crashing your app. It's as simple as:
db.on('error', e => {
console.error('DB error', e);
});
As to why the error happens we need more details, looks like it could be a connection reset due to idle-timeout?
You can create a function to control if you're connected to database or not, before you continue with your main function.
Create a function for controlling database connection status, reconnecting etc. and before you run a database related function, first start that middle function and wait for result, after that you can continue using database again.
If you want(which should be prefered way mostly), create that middle function as an async function and return a promise, when using that function wait for that function.

Mongoose claims I have extra / in DB uri though I do not think I do

I was forced to move DB clusters so I have a new connection string and no actual code changes in the application were made.
When I try to start the application I get the below error message using the following connection string(s), I've included my old one and new one. This cluster is running on Mongo Atlas as a M10 cluster.
Old
mongodb+srv://<myusername>:<mypassword>#production-m0-<account ID?>.mongodb.net
New
mongodb+srv://<myusername>:<mypassword>#production.<account ID?>.mongodb.net
Error message/log
/opt/node_app/node_modules/mongodb/lib/topologies/replset.js:346
throw err;
^
MongoError: database names cannot contain the character '/'
at Function.create (/opt/node_app/node_modules/mongodb-core/lib/error.js:43:12)
at validateDatabaseName (/opt/node_app/node_modules/mongodb/lib/operations/db_ops.js:728:24)
at new Db (/opt/node_app/node_modules/mongodb/lib/db.js:182:3)
at MongoClient.db (/opt/node_app/node_modules/mongodb/lib/mongo_client.js:237:14)
at /opt/node_app/node_modules/mongoose/lib/connection.js:564:62
at /opt/node_app/node_modules/mongodb/lib/utils.js:410:17
at executeCallback (/opt/node_app/node_modules/mongodb/lib/utils.js:402:9)
at /opt/node_app/node_modules/mongodb/lib/operations/mongo_client_ops.js:286:5
at connectCallback (/opt/node_app/node_modules/mongodb/lib/operations/mongo_client_ops.js:265:5)
at /opt/node_app/node_modules/mongodb/lib/operations/mongo_client_ops.js:417:5
at ReplSet.connectHandler (/opt/node_app/node_modules/mongodb/lib/topologies/replset.js:343:9)
at Object.onceWrapper (events.js:300:26)
at ReplSet.emit (events.js:210:5)
at /opt/node_app/node_modules/mongodb-core/lib/topologies/replset.js:786:18
at processTicksAndRejections (internal/process/task_queues.js:75:11) {
driver: true,
name: 'MongoError',
[Symbol(mongoErrorContextSymbol)]: {}
}
Code used in application
const dbString =`${config.db}/mydb?retryWrites=true&w=majority`
mongoose.connect(dbString, { autoReconnect: true, useNewUrlParser: true }, (err) => {
if (!err) console.log('MongoDB has connected successfully.')
});
EDIT as requested combined UrI
mongodb+srv://<myusername>:<mypassword>#production.<account ID?>.mongodb.net/mydb?retryWrites=true&w=majority

How can I get a stack trace into client code with the MongoDB Node.js driver?

I've noticed that MongoDB errors offer rather useless stack traces, pointing only within the driver's internals. The line of code in the client that triggered the error is not output:
const MongoClient = require('mongodb').MongoClient;
MongoClient.connect('...', { useNewUrlParser: true }, async (err, client) => {
try {
// some mongo client code...
// some more mongo client calls...
await client.db().collection('nonexistent').drop();
// yet more mongo client calls...
} catch (e) {
console.error(e);
}
client.close();
});
Here's the output from that:
MongoError: ns not found
at Connection.<anonymous> (/home/dandv/mongostack/node_modules/mongodb-core/lib/connection/pool.js:443:61)
at Connection.emit (events.js:200:13)
at processMessage (/home/dandv/mongostack/node_modules/mongodb-core/lib/connection/connection.js:364:10)
at TLSSocket.<anonymous> (/home/dandv/mongostack/node_modules/mongodb-core/lib/connection/connection.js:533:15)
at TLSSocket.emit (events.js:200:13)
at addChunk (_stream_readable.js:290:12)
at readableAddChunk (_stream_readable.js:271:11)
at TLSSocket.Readable.push (_stream_readable.js:226:10)
at TLSWrap.onStreamRead (internal/stream_base_commons.js:166:17) {
ok: 0,
errmsg: 'ns not found',
code: 26,
codeName: 'NamespaceNotFound',
name: 'MongoError',
[Symbol(mongoErrorContextSymbol)]: {}
}
If there's more than one mongo driver call in the try/catch block, it's impossible to tell which one generated the error.
Is there a way to have those stack traces lead up to client code?

facing problem in connecting mongoDB using the mongoDB client

i am connecting mongodb using the mongodb client in my app.
'app.js' file.
var MongoClient = require('mongodb').MongoClient
MongoClient.connect('mongodb://localhost:27017/animals', function (err, db) {
if (err) throw err
// db.collection('mammals').find().toArray(function (err, result) {
// if (err) throw err
// console.log(result)
// })
})
the issue is:
(node:16348) DeprecationWarning: current URL string parser is
deprecated, and will be removed in a future version. To use the new
parser, pass option { useNewUrlParser: true } to MongoClient.connect.
/home/amarjeet/Desktop/node2/node_modules/mongodb/lib/operations/mongo_client_ops.js:474
throw err;
^
MongoNetworkError: failed to connect to server [localhost:27017] on
first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017]
at Pool.<anonymous> (/home/amarjeet/Desktop/node2/node_modules/mongodb-
core/lib/topologies/server.js:564:11)
at Pool.emit (events.js:188:13)
at Connection.<anonymous>
(/home/amarjeet/Desktop/node2/node_modules/mongodb-core/lib/connection/pool.js:317:12)
at Object.onceWrapper (events.js:276:13)
at Connection.emit (events.js:188:13)
at Socket.<anonymous> (/home/ amarjeet/Desktop/node2/node_modules/mongodb-core/lib/connection/connection.js:246:50)
at Object.onceWrapper (events.js:276:13)
at Socket.emit (events.js:188:13)
at emitErrorNT (internal/streams/destroy.js:82:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
[nodemon] app crashed - waiting for file changes before starting...
so this is the issue is shown on terminal and i have no idea how to fix it!
just add {useNewUrlParser: true } in connection
var MongoClient = require('mongodb').MongoClient
MongoClient.connect('mongodb://localhost:27017/animals', {useNewUrlParser: true }, function (err, db) {
if (err) throw err
// db.collection('mammals').find().toArray(function (err, result) {
// if (err) throw err
// console.log(result)
// })
})
You have to install MongoDB database server first in your system and start it.
if already installed:
check whether server is in start state. and Try connecting with mongo shell
and if server is also in start state:
than just put {useNewUrlParser: true } as mentioned by the #Vaghani Janak

Resources