ETIMEDOUT while using mysql2 with Express on AWS Lambda - node.js

I am using mysql2 package with the Express Framework, deployed over AWS Lamda. I have the provisioned concurrency set to 3 for Aws Lambda.
I am not directly connecting to MySQL. I have RDS Proxy in between.
I am getting the following error, randomly.
{
"errorType": "Error",
"errorMessage": "connect ETIMEDOUT",
"code": "ETIMEDOUT",
"errorno": "ETIMEDOUT",
"syscall": "connect",
"fatal": true,
"stack": [
"Error: connect ETIMEDOUT",
" at Connection._handleTimeoutError (/var/task/node_modules/mysql2/lib/connection.js:178:17)",
" at listOnTimeout (internal/timers.js:554:17)",
" at processTimers (internal/timers.js:497:7)"
]
}
Following is what my code looks like:
var AWS = require("aws-sdk");
const mysql = require('mysql2');
class DBConnection {
constructor() {
var signer = new AWS.RDS.Signer({
region: 'us-east-1',
hostname: process.env.DB_HOST,
port: 3306,
username: process.env.DB_USER
});
let connectionConfig = {
host: process.env.DB_HOST,
user: process.env.DB_USER,
database: process.env.DB_NAME,
ssl: 'Amazon RDS',
authPlugins: { mysql_clear_password: () => () => signer.getAuthToken() }
};
this.db = mysql.createConnection(connectionConfig);
}
query = async (sql, values) => {
return new Promise((resolve, reject) => {
this.db.execute(sql, values, (error, result) => {
if (error) {
reject(error);
return;
}
resolve(result);
});
});
}
}
module.exports = new DBConnection().query;
const results = await query('SELECT COUNT(*) AS total_listens FROM analytics WHERE event_name="PLAYED"');
Any clue where the issue can be?

With AWS Lambda function it's better to use mysql.createPool instead of mysql.createconnection. I don't know what's the specific reason but using mysql.createconnection instead of mysql.createPool has caused problems for me as well. It's also necessary to release the connection when the query goes successful.

Related

Nextjs and Sequelize database connection singleton problem

I'm trying to use nextjs and sequelize together. It works but I have a problem with each request from the database it opens a connection for DB. I have a Db class and export an instance from this class then use it wherever I need.
import { FindOptions, Model, ModelCtor, Sequelize } from 'sequelize'
import { initModels, Models } from './models';
class Db {
connection: Sequelize | null = null;
constructor() {
this.connection = this.connectDb()
initModels(this.connection)
}
retrieveAll(model: ModelCtor<Model<any, any>>, options: FindOptions<any> = {}) {
return model?.findAll(options);
}
retrieve(model: ModelCtor<Model<any, any>>, options: FindOptions<any> = {}) {
return model?.findOne(options);
}
connectDb() {
const dbName = process.env.DB_NAME
const dbHost = process.env.DB_HOST
const dbUser = process.env.DB_USER as string
const dbPassword = process.env.DB_PASSWORD
const sequelize = new Sequelize({
dialect: 'postgres',
host: dbHost,
port: 5432,
database: dbName,
username: dbUser,
password: dbPassword,
pool: {
max: 5,
idle: 86400000,
}
});
try {
sequelize.authenticate();
console.log('Connection has been established successfully.');
return sequelize;
} catch (error) {
console.error('Unable to connect to the database:', error);
return null;
}
}
closeConnectionDb() {
this.connection?.close()
}
}
export const db = new Db();
For example, I make a query database for login then on homepage I get merchant list from the database. I see two times "Connection has been established successfully.". How can I solve this problem? By the way, it works very well in the production server. I think it's about module caching but I'm not sure.

arangojs collections() errors return

I'm totally green with it all. Sorry, but I cant get this thing to work at all node.js + arangojs >
const myColl = async () => {//new Promise((resolve, reject) => {
try {
const db = await new Database({
url: "http://localhost:8529",
databaseName: "testDB",
auth: {username: "userTest", password: "userTest"},
});
console.log(db)
try {
let collection = await db.collections();
console.log(collection);
} catch (err) {
console.log(err);
}
} catch (err) {
console.log("Failed to login db ", err)
return
}
}
myColl()
I just end up with :
Database {_analyzers: Map(0), _collections: Map(0), _graphs: Map(0), _views: Map(0), _connection: Connection, ...}
icAccountController.js:23
Error: connect ECONNREFUSED ::1:8529 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1237:16) at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) {errno: -4078, code: "ECONNREFUSED", syscall: "connect", address: "::1", port: 8529, ...}

Why am I apparently connecting to SQL Azure database using node,js but query is not executed?

I am using the following code to connect to my SQL Azure database using node.js
I took the code from How to connect an existing nodejs server app to Azure SQL database
const express=require('express');
const router = express.Router()
const sql = require('mssql')
const config = {
user: "<user>",
password: "<password>",
server: "<myserver>.database.windows.net",
database: "<mydatabase>",
connectionTimeout: 3000,
parseJSON: true,
options: {
encrypt: true,
enableArithAbort: true
},
pool: {
min: 0,
idleTimeoutMillis: 3000
}
};
const pool = new sql.ConnectionPool(config);
const poolConnect = pool.connect();
router.get('/', async function (req, res) {
console.log('here');
await poolConnect;
try {
const request = pool.request();
const result = await request.query('select 1 as number')
console.log(result);
res.json(result.recordset);
} catch (err) {
console.error('SQL error', err);
res.send(err);
}
});
I know the code is connecting, because if I change the password then I get an error like this
(node:24172) UnhandledPromiseRejectionWarning: ConnectionError: Login failed for user '<user>'.
at Connection.<anonymous> (C:\Users\myuser\node_modules\mssql\lib\tedious\connection-pool.js:68:17)
at Object.onceWrapper (events.js:417:26)
at Connection.emit (events.js:310:20)
at Connection.message (C:\Users\myuser\node_modules\mssql\node_modules\tedious\lib\connection.js:2148:18)
at Connection.dispatchEvent (C:\Users\myuser\node_modules\mssql\node_modules\tedious\lib\connection.js:1279:15)
But if I put the correct password in, then the code just does not output anything at all.
It appears that it is simply not entering the asynchronous function at router.get('/', async function (req, res) {
Any ideas why?
As you stated in your comment, you don't start an express listener or do any requests targeting your express app. So of course, your code will never be executed. If it's just for testing purposes, you don't need express. Just create an async function and call it in your app.
const sql = require('mssql')
const config = {
user: "<user>",
password: "<password>",
server: "<myserver>.database.windows.net",
database: "<mydatabase>",
connectionTimeout: 3000,
parseJSON: true,
options: {
encrypt: true,
enableArithAbort: true
},
pool: {
min: 0,
idleTimeoutMillis: 3000
}
};
const pool = new sql.ConnectionPool(config);
doRequest()
.then(_ => { console.log("succeeded"); })
.catch(e => { console.log("error", e); });
async function doRequest() {
await pool.connect();
let result = await pool.request().query("select 1 as number");
console.log(result);
}
If you really need it in an express app, grab one basic express beginners tutorials which are out there, create a simple express and include your db-request code in one of the route-handlers ...

Can't connect to MongoDB with Nodejs

I am using Node js to try to connect to MongoDB. Here are the related code snippets:
{
"port": 3001,
"appPort": 8080,
"host": "localhost:3001",
"protocol": "http",
"allowedOrigins": ["*"],
"domain": "http://localhost:3001",
"basePath": "",
"mongo": "mongodb://100.10.10.10:27017/database",
"mongoConfig": "",
"mongoCA": "",
"mongoSecret": "--- change me now ---"
}
MongoClient.connect(dbUrl, {useUnifiedTopology: true}, function(err, client) {
if (err) {
console.log(err);
debug.db(`Connection Error: ${err}`);
unlock(function() {
throw new Error(`Could not connect to the given Database for server updates: ${dbUrl}.`);
});
}
db = client.db(client.s.options.dbName);
debug.db('Connection successful');
}
When I use 'npm start' to start the server, I got this error:
MongoServerSelectionError: connect EACCES 100.10.10.10:27017
at Timeout._onTimeout (formio\node_modules\mongodb\lib\core\sdam\topology.js:438:30)
at listOnTimeout (internal/timers.js:549:17)
at processTimers (internal/timers.js:492:7) {
reason: TopologyDescription {
type: 'Unknown',
setName: null,
maxSetVersion: null,
maxElectionId: null,
servers: Map { '100.10.10.10:27017' => [ServerDescription] },
stale: false,
compatible: true,
compatibilityError: null,
logicalSessionTimeoutMinutes: null,
heartbeatFrequencyMS: 10000,
localThresholdMS: 15,
commonWireVersion: null
}
}
I have tried to enable/disable the firewall but the results still don't change. Could you help me fix it?
Thanks
More information about the repository:
https://github.com/formio/formio
https://github.com/Jobin-S/shopping-cart/blob/master/config/connection.js
please look this repository you can see the example.
Make an config file and require it in app.js
const mongoClient = require('mongodb').MongoClient
const state ={
db:null
}
module.exports.connect = (done) => {
const url = 'mongodb://localhost:27017';
const dbName = 'shopping';
mongoClient.connect(url,{ useUnifiedTopology: true }, (err, data) => {
if(err) return done(err)
state.db = data.db(dbName)
done()
})
}
module.exports.get = function(){
return state.db
}
after making this config file.
require config file and require in app.js file and write the code below
var db = require('./config/connection')
db.connect((err)=>{
if(!err) console.log("Database connected successfully");
else console.log(`Connection Error: ${err}`);
})
after that you can use database in any file.
const db = require('../config/connection')
addProduct: (product) => {
return new Promise((resolve, reject) => {
product.Price = parseInt(product.Price)
db.get().collection(collection_name).insertOne(product).then((data) => {
resolve(data.ops[0]._id)
})
})
}

Azure Function app with knex not finishing

I created funnction app and service bus (with topic and its subscriptions), then added function (triggered by new message in topic's sub.). I wanted to write that message to DB (created that db and sql server for it - tried and i coudl connect with my local scripts and clients). Then, I added script's code into index.js in that new function:
module.exports = function(context, mySbMsg) {
context.log('EVENT : ', mySbMsg);
const dbConfig = {
client: 'mssql',
connection: {
server: '---',
user: '---',
password: '---',
options: {
database: '---',
port: 1433,
encrypt: true
}
}
}
const knex = require('knex')(dbConfig);
const newRow = {MessageRecived:mySbMsg}
context.log(' New row : ', newRow);
var res;
return knex.insert(newRow).into('MyEvents').timeout(3000)
.then((output)=>{
context.log(' result : ');
context.log(output);
res = { status: 201, body: "Insert succeeded." };
})
.catch((error) => {
context.log(' error : ');
context.log(error);
res = { status: 500, body: "Error occured" };
})
.finally(() => {
console.log('>> FINALLY');
knex.destroy();
context.done(null, res);
});
};
I dont understand why each request just "hangs" until Fucntion App itself decide it wont finsih, mark it as timeout and leaves. I thought it is becouse of knex, but I added "Destroy"... Still i don't know - Why isn't it working?

Resources