Try Catch 无法捕获 UnhandledPromiseRejectionWarning

tor*_*ard 6 javascript promise puppeteer

我认为我有一个很好的发现来找到我从 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");
            });
})}
Run Code Online (Sandbox Code Playgroud)

这是错误....

(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)
Run Code Online (Sandbox Code Playgroud)

我做了一些研究,说这可能是因为在 puppeteer newPage() 中还有一些 url 尚未完成

但是为什么我的 .catch 没有咳嗽?

我需要它“TRYAGAIN”,以防它因任何原因而失败。现在它只是因错误而停止,什么也不做。

Cer*_*nce 11

您正确地执行catchwaitForSelector及其链接的承诺,但是您没有对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");
  });
}
Run Code Online (Sandbox Code Playgroud)

或者,你可以考虑把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));
Run Code Online (Sandbox Code Playgroud)


AJC*_*C24 7

我要给你的提示是,你可以catch在 Puppeteer 的每一步出错,因为每一步都返回一个承诺。

因此,如果您觉得有必要,可以执行以下操作,而不是 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);
  });
Run Code Online (Sandbox Code Playgroud)

对我来说,这是在每一步捕获任何预期异常的更简洁的方法。