'node.js + mysql: "Cannot enqueue Handshake after already enqueuing a Handshake."
I'm attempting to make two functions, one which retrives an object from an SQL database, the other which saves an object to the same SQL database. I am using node.js
and mysql
to do this. I have two functions, fetchEmployee
and Employee.save
, which fetch and save an employee respectively. When I call fetchEmployee
, and the callback includes Employee.save
, however, I get the error Cannot enqueue Handshake after already enqueuing a Handshake.
Even weirder, Employee.save
seems to run before the error is thrown.
EDIT: employee.save
appearing to run is a symptom of async, as console.log("Saved!")
is called before the callback function passed to SQL.parse
This means the error appears during the parse
. Further, if within parse console.log("connection created");
is added after con.connect
, and console.log("Made it out.");
is added after the end of con.connect
, when calling Employee.save
, the console outputs > "connection created"
, then throws the error, meaning the save query is never finished, but the error is thrown after con.connect
The Employee class is defined by the following
function Employee(obj) {
/** Defines the Employee class
* @arg obj.id : an integer; the employee's id
* @arg obj.name : A string; the employee's name
* @arg obj.position : A string; the employee's positions split by commas
*/
this.id = obj.id;
this.name = obj.name;
this.position = obj.position;
this.save = function() {
SQL.parse({
sql : `UPDATE EMPLOYEES
SET id=?, name=?, position=?
WHERE id=?`,
replace_ : [this.id, this.name, this.position, this.id],
result : false
});
console.log("Saved!");
}
}
Note the console.log("Saved!");
, as this comes up later
fetchEmployee
is defined by this function:
function fetchEmployee(id, callback) {
/** Fetch an employee from the employee table
* @arg id : An integer; the id of the employee to fetch
* @arg callback : A callback function to pass the employee to
*/
SQL.parse({ // Perform the parse, define the sql, replace, and result
sql : "SELECT * FROM employees WHERE id=?",
replace_ : [id],
result : true
},
function(err, data) {
if(err) { // Pass an error if there's an error
callback(err, null);
throw err;
}
// Pass the employee to the callback as an employee object if there's no errors
callback(null, new Employee({ // data is passed as a list from the sql table, so take only the object we need through [0]
id : data[0].id,
name : data[0].name,
position : data[0].position
})
);
});
}
Finally, SQL.parse is defined in this file:
var mySQL = require("mysql");
var con = mySQL.createConnection({ //Create connection
host : "localhost",
database : "testdb1",
user : "root",
password : "***************"
});
function parse(obj, callback) {
/** Parses an sql query.
* @arg callback : A callback function, will be passed the data
* @arg obj.sql : an sql query
* @arg obj.replace_ : A list of replacements for ?s in sql
* @arg obj.result : a boolean indicating whether a result should be returned
*/
//Assign meaningfull values
obj.replace_ = obj.replace_ || [];
callback = callback || function() {};
con.connect(function(err) {
if(err) throw err;
//Connect and pass the sql command to the server
con.query(obj.sql, obj.replace_, function(err, data) {
if(err) { //Pass the err to the callback if there is an err
callback(err, null);
throw err;
}
else if(obj.result) { // Pass the data to the callback if result is true
callback(null, data)
}
});
});
}
module.exports = {
parse : parse
};
When I call this block of code
fetchEmployee(985, function(err, data) {
if(err) throw err;
console.log(data);
data.save();
});
The console outputs
Employee {
id: 985,
name: 'Skidd',
position: 'Dishwasher, Busser',
save: [Function] }
Saved!
Error: Cannot enqueue Handshake after already enqueuing a Handshake. [...]
It appears to me that it correctly runs fetchEmployee
, as data is logged to the console correctly with the data of the employee. It then logs Saved!
, seeming to indicate that Employee.save
ran correctly, then after all the code is done, throws the error. I can't for the life of me figure out why this would happen, here or on google or through testing.
I've tried to add con.end
to the end of parse
in sql.js
, this changes the error to Cannot enqueue Handshake after invoking quit
Solution 1:[1]
I was able to solve this problem by placing
var con = mySQL.createConnection({ //Create connection
host : "localhost",
database : "testdb1",
user : "root",
password : "***************"
});
inside of the parse
function, though I'm not 100% sure why this worked.
Solution 2:[2]
I followed what the previous person did and it worked for me too. I guess the problem was the connection was being made asynchronously. putting this inside the promise solved the problem
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Travis |
Solution 2 | Shweta Singh |