尝试捕获无法捕获UnhandledPromiseRejectionWarning

时间:2018-06-21 07:47:02

标签: javascript promise puppeteer

我以为我发现了从木偶戏中获得的那些罕见的超时,这是一个很好的收获,但是有些人却没有抓住这种超时-我的问题是为什么?

代码如下:

var readHtml = (url) => {
    return new Promise( async (resolve,reject)=> {

        var browser = await puppeteer.launch()
        var page    = await browser.newPage()

        await page.waitForSelector('.allDataLoaded')

            .then(() => {
                console.log ("Finished reading: " + url)
                return resolve("COOL");
            })

            .catch((err) => {
                console.log ("Timeout or other error: ", err)
                return resolve("TRYAGAIN");
            });
})}

这是错误。...

(node:23124) UnhandledPromiseRejectionWarning: Error: Navigation Timeout Exceeded: 30000ms exceeded at Promise.then 

(node:23124) UnhandledPromiseRejectionWarning: 
Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)

我做了一些研究,发现这可能是因为伪造的newPage()内部还有一些未完成的url

但是为什么我的.catch不会引起咳嗽?

如果由于某种原因它失败了,我需要它“尝试”。 现在,它只是因错误而停止,什么也不做。

2 个答案:

答案 0 :(得分:3)

您正确catch waitForSelector及其链接的诺言,但是您对launchnewPage的电话却没有这样做-他们是以后没有连接到catch

由于异步函数已经自动返回Promises,因此您可以考虑完全避免Promise构造函数:

var readHtml = async (url) => {
  try {
    var browser = await puppeteer.launch()
    var page    = await browser.newPage()
  } catch(e) {
    // handle initialization error
  }

  await page.waitForSelector('.allDataLoaded')
    .then(() => {
    console.log ("Finished reading: " + url)
    return resolve("COOL");
  })
    .catch((err) => {
    console.log ("Timeout or other error: ", err)
    return resolve("TRYAGAIN");
  });
}

或者,您可以考虑将catch放入readHtml消费者中:

var readHtml = async (url) => {
  var browser = await puppeteer.launch()
  var page    = await browser.newPage()
  await page.waitForSelector('.allDataLoaded')
  console.log ("Finished reading: " + url)
};
readHtml(someurl)
  .catch((e) => console.log('err: ' + e));

答案 1 :(得分:2)

我要给你的提示是,由于伪造者的每个步骤都会返回承诺,因此您可以在catch的每个步骤中犯错。

因此,如果需要,您可以执行以下操作,而不是使用try / catch块:

const browser = await puppeteer
  .launch()
  .catch(function (error) {
    /* Handle error here for Puppeteer launch and return
       expected value for browser if things fail */
    console.log(error);
  });

const page = await browser
  .newPage()
  .catch(function (error) {
    /* Handle error here for browser new page and return
       expected value for page if things fail */
    console.log(error);
  });

对我来说,这是一种更干净的方法,可以在每个步骤中捕获任何预期的异常。