I have a node.js server-side code that does some basic db operations against mysql. I am using mysql2-promise as the library.
Function layout:
- contacts_GET(contactid) => getContactDetails();
- contacts_GET(email) => getContactId(email) => getContactDetails(contactid);
Function implementations:
contacts_GET : function(args, context, cb){
if (args.pocid !== undefined ){
db.getContactDetails(args.pocid)
.then((results)=>{
var resp = {
"contacts" : results
};
cb(null, resp);
}).catch((reason)=>{
cb(JSON.stringify(errorHandler.throwInternalServerError(reason)));
});
}else if (args.email !== undefined ) {
db.getContactId(null, args.email)
.then((pocid)=>{
logger.debug("got back pocid=", pocid);
return db.getContactDetails(pocid);
}).then((results)=>{
logger.debug("got back result from getContactDetails=", results);
var resp = {
"contacts" : results
};
cb(null, responseObj(resp,args));
}).catch((reason)=>{
cb(JSON.stringify(errorHandler.throwInternalServerError(reason)));
});
}
}
getContactId : function(name, email, conn){
logger.debug("Inside getContactId. [name, email]", name, email);
if (conn === undefined ){
return this.mysql.createConnection(this.options)
.then((conn2)=>{
const b = this.getContactId(name, email, conn2);
conn2.end();
return b;
});
}else{
return conn.execute(`select pocid from Contacts where email = '${email}'`)
.then(([rows, fields])=>{
logger.debug("Inside getContactId. Result:", rows, fields);
if (rows.length == 0) {
return null;
}else{
return rows[0].pocid;
}
});
}
}
getContactDetails : function(pocid, conn){
logger.debug("Inside getContactDetails. [pocid, defined conn]", pocid, (conn!==undefined));
if (conn === undefined ){
return this.mysql.createConnection(this.options)
.then((conn2)=>{
const b = this.getContactDetails(pocid, conn2);
conn2.end();
return b;
});
}else{
const a = conn.execute("select name, email from Contacts where pocid=?", pocid)
.then(([rows, fields])=>{
logger.debug("Inside getContactDetails->cb. Result: ", rows);
if (rows.length == 0) {
return null;
}else{
return rows[0];
}
});
return a;
}
}
Per my understanding, that a Promise returned in a then can be used to chain down, I have composed the chain of promises for the two cases.
When a contactid (pocid) is passed in, only the db.getContactDetails is called. Within this function, it creates a connection (which returns a promise), then executes the query (this returns a promise too), and the result is parsed and resolved. This usecase works.
When an email (email) is passed in, the handler (contacts_GET) creates a chain of promises, starting with getContactId (which returns a promise chaining the connection creation, query execution and result parsing), chained to getContactDetails (same as above). This usecase fails.
My log statements indicate that in the second case, the execution abruptly stops after returning the promise from conn.execute in the getContactDetails function. It appears as if the Promise is never executed, hence the .then part (post execution of the query) never gets called. There are no errors or warnings about unhandled rejections. The control at that point just disappears.
I am struggling to understand why the same function works in the first usecase but fails in the second usecase. I have gone over the Promise documentation and read through every blog about boundary scenarios. I am still at a loss about this and would appreciate all help or pointers.
Thanks!