Home > Mobile >  browser started with puppeteer is not available out of try-catch block
browser started with puppeteer is not available out of try-catch block

Time:01-07

Here is the example code:

"use strict";
const puppeteer = require("puppeteer");

(async () => {
  try {
    const browser = await puppeteer.launch();
    console.log(`browser=${browser}`);
    var cnt_pages = (await browser.pages()).length;
    console.log(`${cnt_pages} pages`);
  } catch (error) {
    console.error(error);
    console.error(`can not launch`);
    process.exit();
  }
  console.log(`browser=${browser}`);

  var cnt_pages = (await browser.pages()).length;
  console.log(`cnt_pages ${cnt_pages}`);
  input("continue?");
})();

As a result, I get

(node:13408) UnhandledPromiseRejectionWarning: ReferenceError: browser is not defined
    at S:\!kyxa\!code\play_chrome_cdp\nodejs_1\!node_tutorial\!play_async\try_catch_browser.js:15:26
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at emitUnhandledRejectionWarning (internal/process/promises.js:168:15)
    at processPromiseRejections (internal/process/promises.js:247:11)
    at processTicksAndRejections (internal/process/task_queues.js:94:32)
(node:13408) ReferenceError: browser is not defined
    at S:\!kyxa\!code\play_chrome_cdp\nodejs_1\!node_tutorial\!play_async\try_catch_browser.js:15:26
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
(node:13408) [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.
    at emitDeprecationWarning (internal/process/promises.js:180:11)
    at processPromiseRejections (internal/process/promises.js:249:13)
    at processTicksAndRejections (internal/process/task_queues.js:94:32)
browser=[object Object]
1 pages

As I see, the browser is available and working in the try block. But after the try-catch block it is not available.

Explain me please what happens?

CodePudding user response:

I've explored the issue. I define the browser value in the try but I also use it in the catch. consts are block-scoped, so they are tied to the block. –

This is the working code:

"use strict";
const puppeteer = require("puppeteer");

(async () => {
  var browser = null;
  try {
    browser = await puppeteer.launch();
    console.log(`browser=${browser}`);
    var cnt_pages = (await browser.pages()).length;
    console.log(`${cnt_pages} pages`);
  } catch (error) {
    console.error(error);
    console.error(`can not launch`);
    process.exit();
  }
  console.log(`browser=${browser}`);

  var cnt_pages = (await browser.pages()).length;
  console.log(`cnt_pages ${cnt_pages}`);
})();

CodePudding user response:

You can elevate let browser out of the block and remove the const, but even after fixing this scoping issue, the browser resource still isn't closed, and any errors that might occur after the try/catch blocks are uncaught. Here's my preferred Puppeteer boilerplate that handles these situations:

const puppeteer = require("puppeteer");

const scrape = async page => {
  // write your code here
  const url = "https://www.example.com";
  await page.goto(url, {waitUntil: "domcontentloaded"});
  console.log(await page.title());
};

let browser;
(async () => {
  browser = await puppeteer.launch();
  const [page] = await browser.pages();
  await scrape(page);
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close());
  • Related