Return error response in nodejs - mysql

Evening stack! Tonight I decided to play around with some NodeJS and I'm having a little trouble understanding the appropriate way for me to handle errors in this situation.
I have a table that simply stores playerName and the name must be unique. So rather than just try to insert and get an error, I want to first make a select and if I get a result, return a 400 to the user and let them know the name already exists. If not, continue on as normal, insert the name, and return a 203.
What I've got clearly isn't working. I've attempted a try/catch and that didn't work. And I clearly can't return an error with the methods I'm using. So what's a good way to go about this?
router.post('/addPlayer' , function(req, res, next){
var playerName = req.body.name;
if(playerName === undefined || playerName.length === 0)
{
return res.status(400).send('No name provided');
}
var query = 'SELECT name FROM players WHERE name LIKE ?';
var inserts = [playerName];
query = connection.format(query , inserts);
connection.query(query, function(err, results){
if(err) return res.status(500).send('Error connecting to database.');
if(results.length !== 0) return res.status(400).send('This name has already been used.');
});
query = 'INSERT INTO players (name) VALUES(?)';
inserts = [playerName];
query = connection.format(query , inserts);
connection.query(query, function(err){
if(err) return res.status(500).send('Error connecting to database.');
});
res.status(201).send("Added player: " + playerName);
});
In this current version my obvious problem is Node crashes complaining about not being able to set the headers after they've already been sent. I know what I need to do. Which is end the execution of the route and return the error to the browser, but I'm just not clear on how to best go about that.
I'm using the Express framework and mysql.
Thanks.

The problem is you're running both queries in parallel. So the INSERT is executed before the response of the SELECT is received. Which means that there is a race condition. Both queries tries to send res.status() but one will happen after the other which causes the error.
To fix this, wait until the SELECT is received then do your INSERT:
var query = 'SELECT name FROM players WHERE name LIKE ?';
var inserts = [playerName];
query = connection.format(query , inserts);
connection.query(query, function(err, results){
if(err) return res.status(500).send('Error connecting to database.');
if(results.length !== 0) return res.status(400).send('This name has already been used.');
query = 'INSERT INTO players (name) VALUES(?)';
inserts = [playerName];
query = connection.format(query , inserts);
connection.query(query, function(err){
if(err) return res.status(500).send('Error connecting to database.');
res.status(201).send("Added player: " + playerName);
});
});

Is there anything wrong with sending the error(err) itself? For example:
if (err)
res.send(err);

Related

How to print the actual query which is being excicuted on node js on console

Hi I am trying the following code
userwallet.post('/api/user/wallet/create',verifyToken,(req,res)=>{
jwt.verify(req.token,'secretkey',(err,authData)=>{
if(err){
console.log(err)
return res.sendStatus('403');
}else{
mysqlConnection.query("INSERT into user_wallets(uuid,user_uuid,balance,status,created_at,updated_at) VALUES(?,?,?,?,?,?)",[uuid(),authData.id,0,'ACTIVE',new Date(),0],(err,rows,fields)=>{
if(!err)
return res.json({
message:"Successfull",
added:rows,
authData
});
console.log('Wallet creation error:',err)
return res.sendStatus('403');
});
}
});
});
There is some trouble of executing this code on the remote machine It is not querying so I am trying to out put the query on console i was going through this answer that is not helpful
NodeJS - how can get mysql result with executed query?
Any suggestions? For troubleshooting
You need to assign connection.query to a variable e.g. query and then can get the sql by query.sql. For more detail
var post = {id: 1, title: 'Hello WORLD'};
var query = connection.query('INSERT INTO TABLENAME SET ?', post, function(err,
result) {
// SOMETHING
});
//HERE YOU CAN GET QUERY
console.log(query.sql);

How to return the response of Node.js mysql query connection

I am new at Node.js and I want to find something from database by using select query.
Here is my code.
var address = socket.request.client._peername.address;
var ip_addrss = address.split("::ffff:");
let mine = ip_addrss[1];
var location = iplocation_find(mine);
connection.connect( function () {
// insert user data with IP, location --- has got a status.
let stranger = "";
var values = [];
if (mine == null){
mine = "local server";
}
values.push(mine);
values.push('location');
var sql = "INSERT INTO user_list (IP_address, location) VALUES (?)";
connection.query(sql, [values], function (err, res){
if (err) throw err;
});
// control chatting connection between users
connection.query("SELECT IP_address FROM user_list WHERE status = ? AND location = ?", [0, "location"], function (err, res){
if (err) throw err;
stranger = res[0].IP_address;
console.log(stranger);
});
var room_users = [];
room_users.push(mine);
room_users.push(stranger);
console.log(room_users);
connection.query("INSERT INTO chatting_status (IP_client_1, IP_client_2) VALUES (?)", [room_users], function (err, res){
if (err) throw err;
console.log('inserted');
});
});
Now the problem is "stranger". It is not working anymore. Just always null.
Please tell me how I can return value in mysql query statement.
on my console, shows this.
[ 'local server', '' ]
127.0.0.1
inserted
[ '192.168.1.100', '' ]
127.0.0.1
inserted
Above, 'local server' and '192.168.1.100' are values of mine. And also '127.0.0.1' is the value of stranger only in query. But out of query it is just null.
You are using asynchronous operations with your .connect() and .query() calls. To sequence code with asynchronous callbacks like this, you have to continue the flow of control inside the callback and then communicate back errors or result via a callback.
You could do that like this:
let address = socket.request.client._peername.address;
let ip_addrss = address.split("::ffff:");
let mine = ip_addrss[1];
let location = iplocation_find(mine);
function run(callback) {
connection.connect( function () {
// insert user data with IP, location --- has got a status.
let values = [];
if (mine == null){
mine = "local server";
}
values.push(mine);
values.push('location');
var sql = "INSERT INTO user_list (IP_address, location) VALUES (?)";
connection.query(sql, [values], function (err, res){
if (err) return callback(err);
// control chatting connection between users
connection.query("SELECT IP_address FROM user_list WHERE status = ? AND location = ?", [0, "location"], function (err, res){
if (err) return callback(err);
let stranger = res[0].IP_address;
console.log(stranger);
let room_users = [];
room_users.push(mine);
room_users.push(stranger);
console.log(room_users);
connection.query("INSERT INTO chatting_status (IP_client_1, IP_client_2) VALUES (?)", [room_users], function (err, res){
if (err) return callback(err);
console.log('inserted');
callback(null, {stranger: stranger, room_users: room_users});
});
});
});
});
}
run((err, result) => {
if (err) {
console.error(err);
} else {
console.log(result);
}
});
Personally, this continually nesting callback code is a drawback of writing sequenced asynchronous code with plain callbacks. I would prefer to use the promise interface to your database and write promise-based code using async/await which will allow you to write more linear looking code.

Mysql search , express response issue

How write a code which will bring me items from MYSQL-DB which will match some of the letters with request? For example I write to the end of link "samsung" but the name of item is "samsung s9, s8 etc...". How to get all of items? This is my code which is note work.
app.get('/models/:name', (req, res, next)=>{
const connection = getConnection();
const queryStr = 'SELECT * FROM products WHERE name=?'
const modelName = req.params.name;
connection.query( queryStr, [modelName], (err, rows, fields)=>{
if (err){
res.send('<h1>500 bad request</h1> Error! Sorry for error, we are working on it!');
res.sendStatus(500);
return;
//throw err;
}
console.log('Ready');
res.json(rows);
})
// res.end();
})
You have to use wildcard character % like 'SELECT * FROM products WHERE name=%anyMobileName%'
IMO Instead of creating MYSQL query from your own and executing these use Sequelize ORM

Save two things at the same time - Node Js

I am currently developing a system where I store custumer's information... One of these information is the custumer's address. To do so, I create two tables in my database: Address and Custumer.
I use the address stored in the custumer table as a foreign key... so far so good. The problem is that I need to first save the address and after get the result id (The id is auto increment) and create the query to save the custumer using that id, but I need to do that at the same function using node, unfortunelly, as I try to do so, I get this error:
'Error: Cannot enqueue Query after invoking quit.'
Below is my code:
this.save = function(connection, object, callback){
let sqlAdress = utilClient.createSaveAdressQuery(object.address);
connection.query(sqlAdress , (error, results) => {
if(error) throw error;
objeto.address.id = results.insertId;
//After that the address is saved, I try to save the client
let sql = utilCliente.createSaveQuery(object);
connection.query(sql, (callback));
})
}
Does anyone know how to help me out? Thanks in advance!
This my callback code:
app.post("/save", function(request, response){
var custumer = request.body;
var connection = dbConnection();
eventoBanco.salvar(connection, custumer, function(error, result){
response.send(result);
if(error != null) console.log(error);
});
connection.end();
});
I think I was able to solve that problem by doing so :
clienteFactoryDAO.alterar(connection, cliente, function(erro, result){
response.send(result);
if(erro != null) console.log(erro);
connection.end();
});
As you can notice now, I close the connection query in the callback passed into the function. MY MISTAKE WAS as the #Himanshusharma nicely pointed: I was closing the connection outside the callback function, and as you know, JavaScript is asynchronous, so it was closing the connection too soon and when I needed one, I got nothing. Thanks in advance and I hope it helps someone at some point

Node Mysql Cannot Enqueue a query after calling quit

where do i close the mysql connection?
I need to run queries in sequence. I am writing code that looks like this at present:
var sqlFindMobile = "select * from user_mobiles where mobile=?";
var sqlNewUser = "insert into users (password) values (?)";
//var sqlUserId = "select last_insert_id() as user_id";
var sqlNewMobile = "insert into user_mobiles (user_id, mobile) values (?,?)";
connection.connect(function(err){});
var query = connection.query(sqlFindMobile, [req.body.mobile], function(err, results) {
if(err) throw err;
console.log("mobile query");
if(results.length==0) {
var query = connection.query(sqlNewUser, [req.body.password], function(err, results) {
if(err) throw err;
console.log("added user");
var user_id = results.insertId;
var query = connection.query(sqlNewMobile, [user_id, req.body.mobile], function(err, results) {
if(err) throw err;
console.log("added mobile");
//connection.end();
});
});
}
});
//connection.end();
(I am a beginner with node, npm-express and npm-mysql. I have tried searching SO for "express mysql cannot enqueue" to find related questions and have not found them.)
I fixed this problem use this method:
connection.end() in your connection.query function
The fixed code is here
If you're using the node-mysql module by felixge then you can call connection.end() at any point after you've made all of the connection.query() calls, since it will wait for all of the queries to finish before it terminates the connection.
See the example here for more information.
If you're wanting to run lots of queries in series, you should look into the async module, it's great for dealing with a series of asynchronous functions (i.e. those that have a callback).
Maybe the problem is that the mySQL query is executed after the connection is already closed, due to the asynchronous nature of Node. Try using this code to call connection.end() right before the thread exits:
function exitHandler(options, err) {
connection.end();
if (options.cleanup)
console.log('clean');
if (err)
console.log(err.stack);
if (options.exit)
process.exit();
}
//do something when app is closing
process.on('exit', exitHandler.bind(null, {cleanup: true}));
Code adapted from #Emil Condrea, doing a cleanup action just before node.js exits
In my case connection.end was being called in a spot that was hard to notice, so an errant call to connection.end could be the problem with this error