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());