Как отловить ошибку от прослушивателя ошибок страницы, прикрепленных к странице Puppeteer? - PullRequest
0 голосов
/ 14 января 2020

Я пишу prerenderer, используя Puppeteer.

Я добавляю функцию, которая позволяет пользователю переключать, должна ли ошибка на отображаемой странице приводить к остановке предварительного рендеринга (посредством отказа от обещания, когда это происходит).

Моя проблема в том, что я не могу поймать отклоненное обещание.

Вот мой код:

async getMarkup(route) {
    const s = this.useHttps === true ? 's' : '';
    const url = `http${s}://localhost:${this.port}${route}`;
    const page = await this.browser.newPage();

    page.on('pageerror', function(err) {
      console.log(err);
      reject(err);
    });

    try {
      await page.goto(url, {timeout: 60000});
      if (this.waitForElement !== null) {
        await page.waitForSelector(this.waitForElement, {timeout: 60000});
      }
      return await page.content();
    } catch (err) {
      throw err;
    }
  }

Я проверяю это, вызывая его на Маршрут с преднамеренной синтаксической ошибкой в ​​сценарии.

Обработчик подключен, но я не могу поймать отклоненное обещание. Это (усеченный) вывод:

[Error: TypeError: (intermediate value).noSuchMethod is not a function
    at window.onload (https://localhost:3005/error_in_js.html:19:41)]
(node:61704) UnhandledPromiseRejectionWarning: ReferenceError: reject is not defined
    at Page.<anonymous> (/Users/andy/repos/ewh-open-source/spa-prerenderer/index.js:164:7)
    at Page.emit (events.js:321:20)
    at Page._handleException (/Users/andy/repos/ewh-open-source/spa-prerenderer/node_modules/puppeteer/lib/Page.js:526:10)
    at CDPSession.<anonymous> (/Users/andy/repos/ewh-open-source/spa-prerenderer/node_modules/puppeteer/lib/Page.js:123:60)
    at CDPSession.emit (events.js:321:20)
    at CDPSession._onMessage (/Users/andy/repos/ewh-open-source/spa-prerenderer/node_modules/puppeteer/lib/Connection.js:200:12)
    at Connection._onMessage (/Users/andy/repos/ewh-open-source/spa-prerenderer/node_modules/puppeteer/lib/Connection.js:112:17)
    at WebSocket.<anonymous> (/Users/andy/repos/ewh-open-source/spa-prerenderer/node_modules/puppeteer/lib/WebSocketTransport.js:44:24)
    at WebSocket.onMessage (/Users/andy/repos/ewh-open-source/spa-prerenderer/node_modules/ws/lib/event-target.js:120:16)

Я экспериментировал с несколькими различными подходами, включая завершение обработчика в новое обещание, назначение его в качестве анонимной асинхронной функции c и затем вызов этого , но это дало аналогичные результаты.

Я предполагаю, что возможно сделать то, к чему я стремлюсь, но, возможно, я иду на это с неправильной стороны. Любая помощь, которая может быть предложена, будет с благодарностью получена в любом случае.

Edit # 1:

Если я переключу линию reject(err) на throw err, происходит то же самое, хотя детали вывода меньше UnhandledPromiseRejectionWarning:

[Error: TypeError: (intermediate value).noSuchMethod is not a function
    at window.onload (https://localhost:3000/error_in_js.html:19:41)]
(node:16112) UnhandledPromiseRejectionWarning
(node:16112) 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(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:16112) [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.

1 Ответ

0 голосов
/ 15 января 2020

resolve или reject должны использоваться внутри обещания иметь функциональность (например, Promise.resolve). Кроме того,

new Promise((resolve, reject) => setTimeout(resolve, 1000))
//and
new Promise((x, y) => setTimeout(x, 1000))

одинаковы, поэтому вам нужно пообещать, что значение reject будет иметь значение.

После catch вы снова выдаете ошибку. Если вы не поймали его где-нибудь за пределами getMarkup, вы увидите то же самое предупреждение.

try {
    await page.goto(url, {timeout: 60000});
    if (this.waitForElement !== null)
        await page.waitForSelector(this.waitForElement, {timeout: 60000});
    return await page.content();
} catch (err) {
    //HERE
    console.error(err.message);
}

Наконец, если ошибка происходит в Javascript веб-страницы, я предлагаю использовать событие window.onerror на странице. Вы можете найти больше информации здесь .

...