Simon H
Simon H

Reputation: 21005

Struggling with a UnhandledPromiseRejectionWarning

I'm struggling to see where the promise rejection is emerging in the following:

MongoClient.connect(mongourl)
    .then(db => {
        console.log("making promises:", typeof lib.getAllData)
        // let promises = packages.map(repo => lib.getAllData(db, repo));
        let promises = [];
        console.log("making promises2")
        // return getAllData(db, packages[0])
        return Promise.all(promises)
            .then(results => {
                console.log("RAW RES", results);
                let missing = results.filter(r => r.error).map(r => r.error)
                return (db, missing);
            })
            // Should never fail as getAllData always resolves
            .catch(err => {
                console.log("err1", err);
                return Promise.reject({db, err})
            });
    }).then(({db, results}) => {
        console.log("RES: ", results);
        db.close();
    }).catch(({db, err}) => {
        console.log("Final Err:", err);
        db.close();
    });

What I see in the console is

making promises: function
making promises2
RAW RES []
RES:  undefined
Final Err: undefined
(node:7026) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: Cannot read property 'close' of undefined
(node:7026) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

I have two questions:

Upvotes: 0

Views: 810

Answers (2)

Simon H
Simon H

Reputation: 21005

So the error was that I was returning - as Dominik stated:

return (db, missing);

That should have been

return {db, missing};

But in my .then I was pattern matching for

{db, results} 

and results could not be found as I was returning a field called missing

Upvotes: 0

Dominik
Dominik

Reputation: 6313

I didn't go through the entire code but from a glance I think you got your deconstructing broken:

const test = () => {
    return ('one','two');
}

console.log( test() )

Will return two, not {'one', 'two'} as you suggest here.

So change your code like this:

MongoClient.connect(mongourl)
    .then(db => {
        console.log("making promises:", typeof lib.getAllData)
        // let promises = packages.map(repo => lib.getAllData(db, repo));
        let promises = [];
        console.log("making promises2")
        // return getAllData(db, packages[0])
        return Promise.all(promises)
            .then(results => {
                console.log("RAW RES", results);
                let missing = results.filter(r => r.error).map(r => r.error)


                return {db, missing};
                //      ^------- THE CHANGE


            })
            // Should never fail as getAllData always resolves
            .catch(err => {
                console.log("err1", err);
                return Promise.reject({db, err})
            });
    }).then(({db, results}) => {
        console.log("RES: ", results);
        db.close();
    }).catch(({db, err}) => {
        console.log("Final Err:", err);
        db.close();
    });

I also suggest to abstract these functions so that you get to a nice promise chain.

Your questions

why is RES undefined - I would expect it to be []

Well you return a single variable rather than an object so db and results is both undefined

why am I ending up at "Final Err" as there should be no rejections occuring in this script

Famous last words ;) Always assume things will break.

Upvotes: 1

Related Questions