The nodemailer connection is forcibly closed in Heroku after 5 min - node.js

I'm using nodemailer library as an SMTP client to send emails outside. I'm also using the option for connection pooling that keeps socket open in the air for 10 min. After the 10 min of inactivity the socket is closing.
smtpClient = nodemailer.createTransport({... pool:true ...});
This is how it looks like when the connection is closing the regular way after the timeout event:
{ component: 'smtp-connection', sid: 'cHH7rJsPKGc' } Timeout
{ component: 'smtp-pool', err: { Error: Timeout
at SMTPConnection._onTimeout (/app/node_modules/nodemailer/lib/smtp-connection/index.js:847:30)
at TLSSocket.SMTPConnection._onSocketTimeout (/app/node_modules/nodemailer/lib/smtp-connection/index.js:199:44)
at TLSSocket.emit (events.js:314:20)
at TLSSocket.EventEmitter.emit (domain.js:483:12)
at TLSSocket.Socket._onTimeout (net.js:484:8)
at listOnTimeout (internal/timers.js:554:17)
at processTimers (internal/timers.js:497:7)
code: 'ETIMEDOUT',
command: 'CONN' }, tnx: 'pool', cid: 1 } Pool Error for #%s: %s
{ component: 'smtp-connection', sid: 'cHH7rJsPKGc', tnx: 'smtp' } Closing connection to the server using "%s"
{ component: 'smtp-pool', tnx: 'connection', cid: 1, action: 'closed' } Connection #%s was closed
When running it on Heroku, it doesn't reach the 10 min but closes after the 4-5 min with an error:
{ component: 'smtp-pool', err: { Error: Unexpected Response: 451 4.7.0 Timeout waiting for client input [xxx.prod.protection.outlook.com]
at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:945:34)
at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:749:14)
at TLSSocket.SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)
at TLSSocket.emit (events.js:314:20)
at TLSSocket.EventEmitter.emit (domain.js:483:12)
at addChunk (_stream_readable.js:298:12)
at readableAddChunk (_stream_readable.js:273:9)
at TLSSocket.Readable.push (_stream_readable.js:214:10)
at TLSWrap.onStreamRead (internal/stream_base_commons.js:188:23)
code: 'EPROTOCOL',
response: '451 4.7.0 Timeout waiting for client input [xxx.prod.protection.outlook.com]',
responseCode: 451,
command: 'CONN' }, tnx: 'pool', cid: 2 } Pool Error for #%s: %s
{ component: 'smtp-pool', tnx: 'connection', cid: 2, action: 'closed' } Connection #%s was closed
{ component: 'smtp-connection', sid: 'Wabdmex9scE', tnx: 'network' } Connection closed
Just to remind, the nodemailer uses Node.js tls.connect() to open a socket:
this._socket = tls.connect(opts, () => {
this._socket.setKeepAlive(true);
this._socket.setTimeout(10 * 60 * 1000);
});
Node.js version: "12.15.0"-"12.19.0"
nodemailer version: "^6.1.1"

Related

ELOGIN Error with Node.js and SQL Server database Connection

I am trying to connect my SQL Database which is in sql server management studio to Node.js. Currently, the connection is being done locally on my machine. This is the error which I keep on getting:
undefined
[nodemon] clean exit - waiting for changes before restart
[nodemon] restarting due to changes...
[nodemon] starting `node server.js`
ConnectionError: Login failed for user 'database access'.
at C:\Users\User\Desktop\PROGRAMMING\Aviation Calc\calc\node_modules\mssql\lib\tedious\connection-pool.js:70:17
at Connection.onConnect (C:\Users\User\Desktop\PROGRAMMING\Aviation Calc\calc\node_modules\tedious\lib\connection.js:1051:9)
at Object.onceWrapper (node:events:510:26)
at Connection.emit (node:events:390:28)
at Connection.emit (C:\Users\User\Desktop\PROGRAMMING\Aviation Calc\calc\node_modules\tedious\lib\connection.js:1079:18)
at C:\Users\User\Desktop\PROGRAMMING\Aviation Calc\calc\node_modules\tedious\lib\connection.js:2608:18
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
code: 'ELOGIN',
originalError: ConnectionError: Login failed for user 'database access'.
at Login7TokenHandler.onErrorMessage (C:\Users\User\Desktop\PROGRAMMING\Aviation Calc\calc\node_modules\tedious\lib\token\handler.js:245:19)
at Readable.<anonymous> (C:\Users\User\Desktop\PROGRAMMING\Aviation Calc\calc\node_modules\tedious\lib\token\token-stream-parser.js:26:33)
at Readable.emit (node:events:390:28)
at addChunk (node:internal/streams/readable:315:12)
at readableAddChunk (node:internal/streams/readable:289:9)
at Readable.push (node:internal/streams/readable:228:10)
at next (node:internal/streams/from:98:31)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
code: 'ELOGIN',
isTransient: undefined
}
}
NOT CONNECTED
undefined
[nodemon] clean exit - waiting for changes before restart
At first I thought that this may be ocurring because I havent enabled windows firewall to allow my port: 1433 but even after doing that I kept on getting the same error message. I also made sure to enable the SQL Server Services in SQL Configuration Manager.
Here is my code:
dbConfig.js
const config = {
// dialect: 'mssql',
user: 'database access',
password: 'tronn6215',
// DESKTOP-NKHJ1GI
// SQLQuery1.sql
server: 'DESKTOP-NKHJ1GI',
database: 'Avtag Data',
options: {
trustServerCertificate: true,
trustedConnection: false,
enableArithAbort: true,
instancename: 'SQLEXPRESS'
},
// dynamic_port: 51582 (dynamic port num)
// port: 50381
port: 1433
//have enabled window firewall to allow static port 1433 for connection but still error
//Now error- code: 'ELOGIN'
}
module.exports = config;
dbOperation.js
const config = require('./dbConfig'),
sql = require('mssql');
const getEntryPoint = async() => {
try {
let pool = await sql.connect(config);
let entry = pool.request().query("SELECT * from ENTRY _POINT1")
console.log(entry);
console.log('CONNECTED')
return entry;
}
catch(error) {
console.log(error);
console.log('NOT CONNECTED')
}
}
module.exports = {
getEntryPoint
}
server.js
const express = require('express'),
dbOperation = require('./dbFiles/dbOperation'),
cors = require('cors');
dbOperation.getEntryPoint().then(res => {
console.log(res);
})

ELOGIN error while connecting to the SQL server

I'm learning full stack web development and was trying to connect to SQL server from my backend Node.js. I was following an online video. While running the index.js file I get the below error -
ConnectionError: Login failed for user 'systemadmin'.
at C:\Users\akunjalw\Desktop\FullStack\server\node_modules\mssql\lib\tedious\connection-pool.js:70:17
at Connection.onConnect (C:\Users\akunjalw\Desktop\FullStack\server\node_modules\tedious\lib\connection.js:1038:9)
at Object.onceWrapper (node:events:640:26)
at Connection.emit (node:events:520:28)
at Connection.emit (C:\Users\akunjalw\Desktop\FullStack\server\node_modules\tedious\lib\connection.js:1066:18)
at Parser.<anonymous> (C:\Users\akunjalw\Desktop\FullStack\server\node_modules\tedious\lib\connection.js:2574:20)
at Object.onceWrapper (node:events:639:28)
at Parser.emit (node:events:520:28)
at Readable.<anonymous> (C:\Users\akunjalw\Desktop\FullStack\server\node_modules\tedious\lib\token\token-stream-parser.js:32:12)
at Readable.emit (node:events:520:28) {
code: 'ELOGIN',
originalError: ConnectionError: Login failed for user 'systemadmin'.
at Login7TokenHandler.onErrorMessage (C:\Users\akunjalw\Desktop\FullStack\server\node_modules\tedious\lib\token\handler.js:239:19)
at Readable.<anonymous> (C:\Users\akunjalw\Desktop\FullStack\server\node_modules\tedious\lib\token\token-stream-parser.js:26:33)
at Readable.emit (node:events:520:28)
at addChunk (node:internal/streams/readable:315:12)
at readableAddChunk (node:internal/streams/readable:289:9)
at Readable.push (node:internal/streams/readable:228:10)
at next (node:internal/streams/from:98:31)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
code: 'ELOGIN',
isTransient: undefined
}
}
undefined
[nodemon] clean exit - waiting for changes before restart
The code is as follows
const sql = require("mssql");
const config = {
user: "systemadmin",
password: "R#jasthaan1212",
server: "localhost",
database: "ORG_EMPLOYEEDATA",
options: {
trustedconnection: true,
trustServerCertificate: true,
enableArithAbort: true,
instancename: "SQL2019",
},
port: 50685,
};
async function getEmployeeName() {
try {
let pool = await sql.connect(config);
let employeeData = await pool
.request()
.query("select * from dbo.EMPLOYEES_DATA");
return employeeData.recordsets;
} catch (error) {
console.log(error);
}
}
module.exports = { getEmployeeName: getEmployeeName };
const dboperations = require("./dboperations");
dboperations.getEmployeeName().then((result) => {
console.log(result);
});
Please let me know what exactly I'm missing here. I couldn't find the way to resolve this by searching in internet as well, may be I'm terrible at searching. Any help to resolve this is appreciated.

ioredis - handle connection retry and ECONNRESET

I'm trying to handle redis retry connection if there's any network issue. It looks like it's working but I'm not sure because sometimes I get ECONNRESET.
redisOptions: {
sentinels: [
{ host: process.env.redis_server_1, port: process.env.redis_port_1 },
{ host: process.env.redis_server_2, port: process.env.redis_port_2 },
{ host: process.env.redis_server_3, port: process.env.redis_port_3 },
],
name: 'mymaster'
},
redisOptions object is defined in configuration file.
function updateConfigurations(){
console.log(configuration.redisOptions);
configuration.redisOptions.sentinelRetryStrategy = (times) => {
console.log('Trying to connect to Redis ', times);
return Math.min(times * 100, 10000);
}
// configuration.redisOptions.retryStrategy = (times) => Math.min(times * 50, 2000);
}
I'm testing this by disconnecting from VPN. The moment I disconnected from VPN, below error message is getting printed on console.
[ioredis] Unhandled error event: Error: read ECONNRESET
at TCP.onStreamRead (internal/stream_base_commons.js:209:20)
And then below logging for retry connecting
[ioredis] Unhandled error event: Error: All sentinels are unreachable. Retrying from scratch after 400ms. Last error: Connection is closed.
Is this a correct way to handle retry connecting? How should I handle ECONNRESET?

Nodemail x Node.js: Failed auth although tested with success

I am having a problem with a nodemailer Firebase Function supposed to send emails through an SMTP transporter.
It is strange because I am testing my connection with success using:
// check server readiness
const serverReady = await new Promise<boolean>(resolve => {
transporter.verify( (err: any, succ: any) => {
if (err) {
console.log(err);
resolve(false);
} else {
console.log('Server is ready to take our messages');
resolve(true);
}
});
})
Which prints Server is ready to take our messages.
Then after setting up my envelope andsending it with th .sendMail method I get this error:
Unhandled error { Error: Mail command failed: 530 5.5.1 Authentication Required.
at SMTPConnection._formatError (/srv/node_modules/nodemailer/lib/smtp-connection/index.js:777:19)
at SMTPConnection._actionMAIL (/srv/node_modules/nodemailer/lib/smtp-connection/index.js:1546:34)
at SMTPConnection._responseActions.push.str (/srv/node_modules/nodemailer/lib/smtp-connection/index.js:1028:18)
at SMTPConnection._processResponse (/srv/node_modules/nodemailer/lib/smtp-connection/index.js:935:20)
at SMTPConnection._onData (/srv/node_modules/nodemailer/lib/smtp-connection/index.js:742:14)
at TLSSocket.SMTPConnection._onSocketData.chunk (/srv/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)
at emitOne (events.js:116:13)
at TLSSocket.emit (events.js:211:7)
at addChunk (_stream_readable.js:263:12)
at readableAddChunk (_stream_readable.js:250:11)
at TLSSocket.Readable.push (_stream_readable.js:208:10)
at TLSWrap.onread (net.js:601:20)
code: 'EENVELOPE',
response: '530 5.5.1 Authentication Required.',
responseCode: 530,
command: 'MAIL FROM' }
The error is pretty clear: Failed Auth but it's strange since the test worked earlier!
Connection parameters are:
// options to connect to server
const smtpOptions = {
host: 'smtp.zoho.eu',
port: 465,
secure: true,
auth: {
user: functions.config().nodemailer.user,
pass: functions.config().nodemailer.pass
}
};
// transporter for sending the email
const transporter = nodeMail.createTransport( smtpOptions );
Thank you guys in advance
transporter.verify only tests the connection and authentication, it looks like the that you are not authorised to use the particular MAIL FROM address.

AWS Lambda external URI request error: connect ETIMEDOUT

I coded in my local dev environment a node.js function that does several requests to an external url-uri (asynchronously using bluebird and request-promise). It works fine, the function gets the results and save the information into the EC3 database.
The problem comes when I deploy the code (node modules included), and execute it. It has access to the database, but when tries to access to external url-uri the 'request-promise' module gets an 'connect ETIMEDOUT' error.
I did all the AWS indicates to get it, and read and try a all the solutions I found in Stackoverflow, but still having the problem.
https://www.youtube.com/watch?v=AR1nt3iGR5o
The related role that runs the function has the following policies:
AWSLambdaFullAccess - AWSCodeDeployRoleForLambda - AmazonVPCFullAccess - AWSLambdaExecute - AWSLambdaBasicExecutionRole - AWSLambdaVPCAccessExecutionRole - AWSLambdaRole - oneClick_lambda_basic_execution_1535968782861
Function Network Config
Nat getway
Route Table
Could you help me please, or at least give a hint, please?
CODE:
const Promise = require('bluebird');
const Rp = require('request-promise');
const http = require('http');
var httpAgent = new http.Agent();
httpAgent.maxSockets = 15;
var promises = urls.map(function(url){
return Rp({uri: url.url, pool:httpAgent}).then(function(result){
url.result = result;
// Saving space
delete url.url;
return url;
})
});
Promise.all(promises).then(function(results){
return(processResults(results));
}).catch(Error, function (e) {
console.error("Error doing Request: ", e);
}).error(function (e) {
console.error("Unable get info: ", e);
}).then(function(results){
try{
product.callback(results);
}catch (exception) {
console.error('Error callback: ',exception);
}
}).then(function(){
product.finally();
});
ERROR:
2018-09-28T14:53:48.989Z efb5493a-c32d-11e8-ae42-f73dec33ca2a Error doing Request: { RequestError: Error: connect ETIMEDOUT 147.83.184.65:80
at new RequestError (/var/task/node_modules/request-promise-core/lib/errors.js:14:15)
at Request.plumbing.callback (/var/task/node_modules/request-promise-core/lib/plumbing.js:87:29)
at Request.RP$callback [as _callback] (/var/task/node_modules/request-promise-core/lib/plumbing.js:46:31)
at self.callback (/var/task/node_modules/request/request.js:185:22)
at emitOne (events.js:116:13)
at Request.emit (events.js:211:7)
at Request.onRequestError (/var/task/node_modules/request/request.js:881:8)
at emitOne (events.js:116:13)
at ClientRequest.emit (events.js:211:7)
at Socket.socketErrorListener (_http_client.js:387:9)
at emitOne (events.js:116:13)
at Socket.emit (events.js:211:7)
at emitErrorNT (internal/streams/destroy.js:64:8)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickDomainCallback (internal/process/next_tick.js:218:9)
name: 'RequestError',
message: 'Error: connect ETIMEDOUT 147.83.184.65:80',
cause:
{ Error: connect ETIMEDOUT 147.83.184.65:80
at Object._errnoException (util.js:1022:11)
at _exceptionWithHostPort (util.js:1044:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1198:14)
code: 'ETIMEDOUT',
errno: 'ETIMEDOUT',
syscall: 'connect',
address: '147.83.184.65',
port: 80 },
error:
{ Error: connect ETIMEDOUT 147.83.184.65:80
at Object._errnoException (util.js:1022:11)
at _exceptionWithHostPort (util.js:1044:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1198:14)
code: 'ETIMEDOUT',
errno: 'ETIMEDOUT',
syscall: 'connect',
address: '147.83.184.65',
port: 80 },
options:
{ uri: 'http://geoserver.hydsdev.net/geoserver/mhews/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetFeatureInfo&FORMAT=image%2Fjpeg&TRANSPARENT=true&INFO_FORMAT=text%2Fxml&FEATURE_COUNT=50&X=50&Y=50&SRS=EPSG%3A4326&WIDTH=101&HEIGHT=101&QUERY_LAYERS=mhews:ffews_rain_accumulation_15min_opera&LAYERS=mhews:ffews_rain_accumulation_15min_opera&BBOX=0.6319608%2C42.770155%2C0.8319608%2C42.870155000000004&TIME=2018-09-28T17:30:00.000Z',
pool:
Agent {
domain: null,
_events: [Object],
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 80,
protocol: 'http:',
options: [Object],
requests: {},
sockets: {},
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: 15,
maxFreeSockets: 256,
'http:': [Object] },
callback: [Function: RP$callback],
transform: undefined,
simple: true,
resolveWithFullResponse: false,
transform2xxOnly: false },
response: undefined }
Cheers.
Finally I fixed the problem. Don't know why but into 'request-promise' options object I have to put: headers: {'User-Agent':'request' } . Thank you very much #Rajesh!

Resources