sigil
sigil

Reputation: 9546

Trying to pass a Promise to another function that then returns it, getting "Unhandled promise rejection"

I want to create a generic database update function that I can use to implement more customized update functions. In a module database.js I have the following:

const {Pool,Client}=require('pg');

const pool=new Pool({
    connectionString:process.env.HEROKU_POSTGRESQL_URL,
    ssl:true
});

function update(sql,functionName){
    console.log(sql);
    return new Promise(function(resolve,reject){
            pool.query(sql,(err,res)=>{
                if (err){
                    console.log(functionName+": error "+err.toString());
                    reject(res);
                }
                else{
                    console.log(functionName+": non-null");
                    console.log(functionName+": result "+JSON.stringify(res.rows[0]));
                    resolve(res.rows[0]);
                }
            });
        });
}

module.exports = {
    updateConnection: function(callSid,connectionStatus){
        queryStr='update connection set hoststatus=\''+connectionStatus+'\' where hostCallSid=\''+callSid+'\' returning *';
        return update(queryStr,"updateConnection");
    },

//...various other updateSomething functions with variations on queryStr
}

I test this in another module dbtest.js as follows:

var db=require('./src/ivr/database');

testUpdateConnection();

function testUpdateConnection(){
    hostCallSid="yourCallSidHere";
    db.updateConnection(hostCallSid,"accepted").then(val=>{console.log(val.rows[0])});
}

Originally I had all the Promise creation code from update() inside updateConnection(), and it worked as expected, but because I had to copy-paste this code into every update function, I decided to refactor it into its own separate function. Now when I run node dbtest, the update successfully occurs and the console.log() output from update() is shown, but then I get the following:

(node:10) UnhandledPromiseRejectionWarning: TypeError: Cannot read property '0' of undefined
    at db.updateConnection.then.val (/app/dbtest.js:73:77)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:10) UnhandledPromiseRejectionWarning: Unhandled promise rejection.

It seems that updateConnection() isn't being treated as a promise-returning function, even though it's passing along the promise returned from update(). Is there a way that I can solve this without having to include the code from update() in every one of the update functions in database.js?

Upvotes: 0

Views: 45

Answers (1)

jfriend00
jfriend00

Reputation: 707148

Your update() function has already gotten the first row in resolve(res.rows[0]);. So, when you try to do that again with val.rows[0], that won't work. That's like trying to do res.rows[0].rows[0] which throws an exception.

Change your function from this:

function testUpdateConnection(){
    hostCallSid="yourCallSidHere";
    db.updateConnection(hostCallSid,"accepted").then(val=>{console.log(val.rows[0])});
}

to this:

function testUpdateConnection(){
    hostCallSid="yourCallSidHere";
    db.updateConnection(hostCallSid,"accepted").then(val=>{console.log(val)});
}

Or, change update() to just resolve(res). One or the other.

Upvotes: 1

Related Questions