Puppeteer Google Cloud Function发布/订阅触发器无法打开浏览器

时间:2019-06-13 12:49:32

标签: google-cloud-functions puppeteer google-cloud-pubsub

我正在尝试在GCP中创建一个Puppeteer函数,该函数可以由发布/订阅消息触发。该函数是可调用的,但未达到预期的效果,并且一旦浏览器尝试初始化,就会引发“超时错误”。触发器可能使用与HTTP触发器不同的NodeJS环境吗?

我对NodeJS也很陌生,所以如果问题很明显,我会提前道歉。

我已经为该函数创建了一个HTTP触发器,该触发器的行为符合预期。创建Cloud Function时,我将下面的Puppeteer Function复制/粘贴到index.js中,但是为了清楚起见,两个触发器都运行相同的功能,在示例中进行了分隔。

木偶功能

const puppeteer = require('puppeteer');

scrapeUglyWebsite = () => {
    return new Promise(async(resolve, reject) => {
        await puppeteer.launch({
            headless: true,
            args: ['--no-sandbox']
        })
            .then(async (browser) => {
                const page = await browser.newPage();
                await page.goto('http://suzannecollinsbooks.com/', {waitUntil: 'load', timeout: 0})
                    .then(async () => {
                        //Wait for content to load
                        await page.waitForFunction('document.body !== null && document.body.innerText.includes(\'Jon Scieszka\')');
                        //Evaluate page contents
                        const dom_eval = await page.evaluate(() => document.body.innerText.includes("Here’s a picture of me with a rat"));
                        await browser.close();
                        resolve(dom_eval);
                    });
            }).catch((err) => {
                reject(err);
            });
    });
};

HTTP触发器-index.js

exports.cloudFunctionTest = (req, res) => {
    scrapeUglyWebsite()
        .then((results) => {
            if(results) {
                res.send('Suzanne Collins takes pictures with rats.');
            } else {
                res.send("Suzzane Collins doesn't take pictures with rats.");
            };
        })
        .catch((err) => {
            res.send(err.toString());
        });

Pub / Sub Trgger-index.js

exports.cloudFunctionTest = (data, context) => {
    scrapeUglyWebsite()
        .then((results) => {
            if(results) {
                console.log('Suzanne Collins takes pictures with rats.');
            } else {
                console.log("Suzzane Collins doesn't take pictures with rats.");
            };
        })
        .catch((err) => {
            console.log(err.toString());
        });
};

package.json

{
  "name": "test",
  "version": "0.0.1",
  "engines": {
    "node": "8"
  },
  "dependencies": {
    "puppeteer": "^1.6.0"
  }
}

HTTP触发器的行为正常,具有预期的结果

Suzanne Collins takes pictures with rats.

Pub / Sub触发器引发以下错误,但没有输出

TimeoutError: Timed out after 30000 ms while trying to connect to Chrome! The only Chrome revision guaranteed to work is r662092

1 个答案:

答案 0 :(得分:0)

我知道这很晚,但是发生TimeoutError的原因是因为云功能不会自动等待异步任务完成。因此,在exports.cloudFunctionTest中,scrapeUglyWebsite()被调用,但是该函数不等待承诺被兑现,因此程序终止。因此错误

有关后台功能如何在NodeJ中工作的更多信息here

为了使函数等待scrapeUglyWebsite(),您需要返回一个在scrapeUglyWebsite()并且结果代码完成时完成的承诺。

就个人而言,我只需将当前导出的函数中的代码包装到另一个异步函数中,然后返回包装函数的承诺即可。

async function wrapper() {
    try {
        const result = await scrapeUglyWebsite(); 
        if(results) {
            console.log('Suzanne Collins takes pictures with rats.');
        } else {
            console.log("Suzzane Collins doesn't take pictures with rats.");
        };
    } catch (err) {
        console.log(err.toString());
    }
}

然后在您要导出的功能中:

exports.cloudFunctionTest = (data, context) => {
    return wrapper();
};