Void
Void

Reputation: 67

Cannot resolve Promise in Node.js App with chrome-cookies-secure module

I'm working on a local Node.js app that needs to access the Google Chrome cookies. I've found the chrome-cookies-secure library that seems to do the job but I just can't figure out what's wrong with the code below.

const chrome = require('chrome-cookies-secure');

const domains = [
    "google.com"
];

const resolveCookies = async () => {
    let result = [];
    for(domain of domains) {
        await chrome.getCookies(`https://${domain}/`,  (err, cookies) => { 
            result.push(cookies); 
            // console.log(cookies); //? This is going to correctly print the results
        })
    }
    return result;
}

const final = resolveCookies();
console.log(final); //! This is going to return a Promise { <pending> } object

The idea is that I just want to store the cookies from all the domains in a list but no matter what I cannot resolve the Promise. I didn't see any examples with the async call for this module but if I don't use it it's going to return me an empty list after the script execution.

My Node Version: v14.4.0

What am I doing wrong?

Upvotes: 2

Views: 547

Answers (3)

jonrsharpe
jonrsharpe

Reputation: 122090

It looks like the implementation of getCookies is not correctly awaiting the asynchronous processes. You can see in the implementation that although getCookies itself is async, it calls getDerivedKey without awaiting it (and that function isn't async anyway).

Rather than trying to rely on this implementation, I'd suggest using Util.promisify to create a proper promise via the callback:

const util = require('util');

const chrome = require('chrome-cookies-secure');

const getCookies = util.promisify(chrome.getCookies);

// ...

const cookies = await getCookies(`https://${domain}/`);

Note that, as Reece Daniels pointed out in the comments, the getCookies implementation actually takes a profile parameter after the callback; if you need to use that parameter, you can't use the built-in promisify. You'd have to wrap it yourself instead, this could look like e.g.:

const getCookies = (url, format, profile) => new Promise((resolve, reject) => {
    chrome.getCookies(url, format, (err, cookies) => {
        if (err) {
            reject(err);
        } else {
            resolve(cookies);
        }
    }, profile);
});

They already tried to fix the promise upstream, but the PR hasn't been merged in nearly nine months.


Note that once you have a working function to call you can also convert:

const resolveCookies = async () => {
    let result = [];
    for(domain of domains) {
        await chrome.getCookies(`https://${domain}/`,  (err, cookies) => { 
            result.push(cookies); 
            // console.log(cookies); //? This is going to correctly print the results
        })
    }
    return result;
}

to simply:

const resolveCookies = () => Promise.all(domains.map((domain) => getCookies(`https://${domain}/`)));

Upvotes: 3

Rajeshwaran P
Rajeshwaran P

Reputation: 69

try this.

const chrome = require('chrome-cookies-secure');

const domains = [
    "www.google.com"
];

const resolveCookies = async() => {
    let result = [];
    for (domain of domains) {
      const cookies = await getCookies(domain)
      result.push(cookies)
    }
    return Promise.resolve(result);
}

const getCookies = async (domain) => {
    chrome.getCookies(`https://${domain}/`,  (err, cookies) => { 
        return Promise.resolve(cookies);
    })
}

resolveCookies().then((resp) => {
    console.log('FINAL ',resp)
}).catch((e) => {
    console.log('ERROR ', e)
})

Upvotes: -1

Dimitris Kirtsios
Dimitris Kirtsios

Reputation: 317

An async function returns a Promise. So your resolveCookies function will also return a Promise as you noticed.

You need to either chain the console.log with a .then e.g.

resolveCookies().then(console.log);

Or if you need to set it to a variable like final you need to await that Promise too. In that case you need an async IIFE:

(async () => {
    const final = await resolveCookies();
    console.log(final);
})();

Upvotes: -1

Related Questions