Why MySQL connection lost in nodejs? - javascript

I am creating a facebook chatbot using node js and to store data I used MySQL Database. Currently it is working fine. But, I have a question that, should I need to close the database connection?
I tried to do it but when I close the connection then in the next attempt it is throwing an error that No SQL Connection found
Please tell me the correct way of how to close database connection and reuse it
let databaseConnection = () =>{
let conn = mysql.createConnection({
host: "",
user: "",
password: "",
database: "",
port: ""
});
conn.connect(function (error) {
if (error) {
console.log("Error when connecting to db ",error);
setTimeout(databaseConnection, 2000);
}
else {
console.log("Connected");
}
});
conn.on('error',function(err){
console.log('db error', err);
if(err.code === 'PROTOCOL_CONNECTION_LOST') {
databaseConnection();
}else{
throw err;
}
});
return conn;
}
conn = databaseConnection();
for (let i=0;i<10;i++){
query = "SELECT name FROM info where id=?";
value = i
conn.query(query,value, function (err, result, fields) {
if (err) throw err;
console.log(result);
console.log("Data Fetched Successfully.")
})
conn.end()
}

You should end your connection after the loop
for (let i=0;i<10;i++){
query = "SELECT name FROM info where id=?";
value = i
conn.query(query,value, function (err, result, fields) {
if (err) throw err;
console.log(result);
console.log("Data Fetched Successfully.")
})
}
conn.end()

Related

Connect Vertica DB from node and Typescript application

I'm writing d3 visualization code to append counts and rectangle boxes around the counts on .JPEG image. In order to get dynamic data I used typescript+node JS+D3 JS. I need to use Vertica DB.
How to install plugin to connect to db from typescript+nodeJS?
I tried node-vertica plugin and could not integrate it properly.
---------------
Code in app.js:
---------------
var config = {
ssl: 'optional',
interruptible: true,
host: '*******',
user: '*********',
password: '********',
database: '********'
};
try {
conn = Vertica.connect(config, (err, conn) => {
if (err) {
console.log(err);
} else {
conn.connect(function(err) {
if (err) throw err;
conn.query("select * from *****", function (err, result, fields) {
if (err) throw err;
console.log(result);
});
});
}
});
}
catch (error) {
console.log("Error has been caught --"+error);
}

nodejs mysql on pool connection Error: Connection lost: The server closed the connection

My question is similar to this post but the solution didnt work for me probably because im using a different type of mysql connection (pool). This is my code:
let config= {
host: '***',
user: 'admin',
password: '***,
port: '3306',
database: '***',
multipleStatements: true
};
const con = mysql.createPool(config);
select();
function select(){
return new Promise((resolve, reject) => {
con.getConnection(function (err, connection) {
if (err) throw err;
else
console.log("Connected!");
let sql = "SELECT * FROM bidPrice WHERE idExchangePlatform = 2;";
connection.query(sql, function (err, results, fields) {
connection.release();
connection.destroy();
if (err) throw err;
console.log(results)
resolve(results);
});
});
});
}
I also important to mention that im running this function using the following command
node --max-old-space-size=31744 index.js # Increase to 31 GB
This is because im working with millions of records from the database query
If i run this with regular node command i would be getting Javascript heap out of memory
When i tried integrating the solution i mentioned earlier to my code i just get a "killed" log after a while and then the process stops, should i handle server disconnect in a different way when using mysql.pool?
If you have big table with many rows, you will must check index for column 'idExchangePlatform' and create if doesn't make it
And simple variant your code:
function select(){
return new Promise((rs, rj) => {
let sql = "SELECT * FROM bidPrice WHERE idExchangePlatform = 2;";
pool.query(sql, (err, rows) => {
if(err)
return rj(err);
return rs(rows);
})
});
}

Node.js - PostgreSQL (pg) : Client has already been connected. You cannot reuse a client

I am just trying to write simple register/login system.
I am trying to find if username exists. Here is the steps :
Go localhost:3000/users/register page
Fill in all fields and click register button
Checking my command line if username exists it should print it with console.log
Everything works fine until now.
When I go back to the register page, I fill in all fields again and click register button. Then it throws it in command line :
Error: Client has already been connected. You cannot reuse a client.
at Client._connect (C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\node_modules\pg\lib\client.js:91:17)
at C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\node_modules\pg\lib\client.js:310:10
at new Promise (<anonymous>)
at Client.connect (C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\node_modules\pg\lib\client.js:309:10)
at Object.module.exports.findUserById (C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\database\register_sql.js:8:22)
at C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\routes\users.js:37:29
at Layer.handle [as handle_request] (C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\node_modules\express\lib\router\route.js:137:13)
at next (C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\node_modules\express\lib\router\route.js:131:14)
at Route.dispatch (C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\node_modules\express\lib\router\route.js:112:3)
I dont understand because I already end my client after I call my method.
register_sql.js :
module.exports.findUserById =(async (username) =>{
try {
await client.connect();
console.log('Connected successfuly');
const result = await client.query("select * from users where username = ($1)", [username]);
console.log(result.rows[0]['username']);
await client.end();
console.log('Client disconnected...');
} catch (err) {
console.log(err);
}
});
I call register_sql.js in users.js. Here is users.js :
const router = express.Router();
const registerSQL = require('../database/register_sql');
router.route('/register')
.get((req, res, next) => {
res.render('register');
})
.post((req, res, next) => {
const {
username,
password,
password2
} = req.body;
let errors = [];
if (!username || !password || !password2) {
errors.push("Please fill in all fields!");
}
if (password != password2) {
errors.push("Passwords do not match!");
}
if (password.length < 6) {
errors.push("Password has to be at least 6 characters!");
}
if (errors.length > 0) {
res.render('register', {
errors
});
} else {
registerSQL.findUserById(username);
res.redirect('/');
}
});
module.exports = router;
Thank you for helping!
With node-postgres (which is the one you're using) I've only made it work using the pool do manage the connections.
const pg = require('pg')
const pool = new pg.Pool();
pool.connect(function(err, client, done) {
if(err) {
return console.error('connexion error', err);
}
client.query("select * from users where username = ($1)", [username], function(err, result) {
// call `done()` to release the client back to the pool
done();
if(err) {
return console.error('error running query', err);
}
console.log(result.rows[0]['username'])
});
});
I had the same problem, dont create the new Client outside the function.
- const client = new pg.Client(connection);
-
function test() {
+ const client = new pg.Client(connection);
+
client.connect(err => {
if (err) {
console.log(err);
return;
}
client.query('select 123', [], (err, data) => {
if (err) {
console.log(err);
} else {
console.log('DATA:', data.rows[0]);
}
client.end();
});
});
}
I managed to fix this problem without using pool. Maybe that's not the most correct solution, but it works.
First create a separate js file, where you connect the client and export it:
const pg = require('pg')
const client = new pg.Client('your connection string')
client.connect()
module.exports = client
Then you just use the exported client, which has already been connected, so it won't reconnect again on each request. Be sure to import the client from the js file where you connect it.
const client = require('../db')
const register = async (req, res) => {
const {email, password, username} = req.body
const hashedPassword = await bcrypt.hash(password, 10)
const command = `insert into users(email, username, password, created) VALUES ('${email}', '${username}', '${hashedPassword}', current_timestamp)`
await client.query(command, (err, result) => {
err ? res.json({error: err.detail}) : res.json({message: 'User created!'})
})
}
well the problem occur because you haven't closed the connection to database.
Remember you have to close the connection before you sent something to client like that:
try {
await client.connect();
const result = await client.query(query, values);
await client.end();
res.status(201).send({
result,
});
} catch (err) {
return res.send({
error: err.detail,
message: "Can't create a new user, please check your info again!",
});
}
Pool approach is better practice but if someone want to connect with Client approach then this solution will work.
Code which will work with Client approach :
client.connect();
client.query(`select * from users where username = ($1)`, (err, result)=>{
try{
console.log("Test", result)
res.send(result)
} catch{
console.log("err", err)
res.status(500).json(err);
}
client.end();
})

running nodejs and mysql, how can I parse the result in client

var mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "yourusername",
password: "yourpassword",
database: "mydb"
});
con.connect(function(err) {
if (err) throw err;
con.query("SELECT * FROM customers", function (err, result, fields) {
if (err) throw err;
console.log(result);
});
});
in my c# I have
IRestResponse response = client.Execute(request);
var content = response.Content;
but the content prints "Internal Error" for all err types
EDIT
Also tried:
pool.getConnection((err, conn) => {
if(err) {
var error = new Error("something is wrong");
callback(error);
}
according to this https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-mode-exceptions.html, still getting Internal Error for all error types
Also, I do get 200 OK on good requests, what I am trying to do is to print an explanatory message to the client in case of an error

Error from node-js mysql connection doesn't get saved to array

Im trying to keep a record from all my errors in a WebService I'm making in node-js;
I've written the following code to keep track of a mysql query possible error:
var err_db = [];
try{
if(error.length == 0){
...
var con = mysql.createConnection({
host: "my_host",
user: "my_user",
password: "my_pass",
database: "my_db"
});
con.connect(function(err) {
if (err) err_db[err_db.length] = err.message;
con.query("IM TRYING HARD TO GET AN SQL ERROR", function (err) {
if (err) err_db[err_db.length] = err.message;
console.log(err_db); //FIRST LOG SHOWS CORRECT
});
console.log(err_db); // THE ERROR DISAPEARS FROM ARRAY
});
}
}
catch(err){
if(err) err_db[err_db.length] = err.message;
}
The problem is the error only keeps stored in array inside the con.query function, after that it disappear, and I want to keep it in a array because later on I intend in sending this possible errors as a JSON to through the WebService response. Thanks in advance.
This is a normal asynchronous nature of node.js. Since the query is executed in a slight greater time so next line is executed first.
try{
if(error.length == 0){
...
var con = mysql.createConnection({
host: "my_host",
user: "my_user",
password: "my_pass",
database: "my_db"
});
con.connect(function(err) {
if (err) err_db[err_db.length] = err.message;
con.query("IM TRYING HARD TO GET AN SQL ERROR", function (err) {
if (err) err_db[err_db.length] = err.message;
console.log(err_db); //FIRST LOG SHOWS CORRECT
// throw the error from here
});
console.log(err_db); // THIS EXECUTED EARLIER THAN THE PREVIOUS
});
}
}
catch(err){
if(err) err_db[err_db.length] = err.message;
}
Asynchronous code cannot catch exceptions using try-catch.
You can try the following code.
var EventEmitter = require('events');
var emitter = new EventEmitter();
var err_db = [];
var con = mysql.createConnection({
host: "my_host",
user: "my_user",
password: "my_pass",
database: "my_db"
});
if (error.length == 0) {
con.connect(function (err) {
if (err) {
emitter.emit('err_db', err);
return;
}
con.query("IM TRYING HARD TO GET AN SQL ERROR", function (err) {
// if (err) err_db[err_db.length] = err.message;
// console.log(err_db); //FIRST LOG SHOWS CORRECT
if (err) {
emitter.emit('err_db', err);
return;
}
});
console.log(err_db); // THE ERROR DISAPEARS FROM ARRAY
});
}
emitter.on('err_db', (err) => {
// handle db err...
err_db[err_db.length] = err.message
});

Categories