最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - UnhandledPromiseRejectionWarning: Error: Page crashed! While using puppeteer - Stack Overflow

programmeradmin5浏览0评论

So I used a while loop so my test will run in a constant loop until my back-end will crash. I've implemented a try and catch(error) so any front-end crash the automation will refresh and keep running

while(true){
try{
    await page.waitFor(selector)
    await page.click(selector)    
}
catch(error){
    console.log("FE crashed with\n\n" + error + "\n\nRefreshing page and continuing profile switching")
    await page.reload(page);
    continue;
}}

So indeed any timeout error the automation refreshes the page and continuing the loop. but Im recieving a different crash error

(node:6535) UnhandledPromiseRejectionWarning: Error: Page crashed!
at Page._onTargetCrashed (/home/raymond/node_modules/puppeteer/lib/Page.js:170:24)
at CDPSession.Page.client.on.event (/home/raymond/node_modules/puppeteer/lib/Page.js:125:56)
at CDPSession.emit (events.js:182:13)
at CDPSession._onMessage (/home/raymond/node_modules/puppeteer/lib/Connection.js:200:12)
at Connection._onMessage (/home/raymond/node_modules/puppeteer/lib/Connection.js:112:17)
at _tickCallback (internal/process/next_tick.js:43:7)
at listOnTimeout (timers.js:294:7)
at processTimers (timers.js:268:5)
(node:6535) 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)

How can I handle this error?, if I refresh the page manually everything works fine. Thanks

So I used a while loop so my test will run in a constant loop until my back-end will crash. I've implemented a try and catch(error) so any front-end crash the automation will refresh and keep running

while(true){
try{
    await page.waitFor(selector)
    await page.click(selector)    
}
catch(error){
    console.log("FE crashed with\n\n" + error + "\n\nRefreshing page and continuing profile switching")
    await page.reload(page);
    continue;
}}

So indeed any timeout error the automation refreshes the page and continuing the loop. but Im recieving a different crash error

(node:6535) UnhandledPromiseRejectionWarning: Error: Page crashed!
at Page._onTargetCrashed (/home/raymond/node_modules/puppeteer/lib/Page.js:170:24)
at CDPSession.Page.client.on.event (/home/raymond/node_modules/puppeteer/lib/Page.js:125:56)
at CDPSession.emit (events.js:182:13)
at CDPSession._onMessage (/home/raymond/node_modules/puppeteer/lib/Connection.js:200:12)
at Connection._onMessage (/home/raymond/node_modules/puppeteer/lib/Connection.js:112:17)
at _tickCallback (internal/process/next_tick.js:43:7)
at listOnTimeout (timers.js:294:7)
at processTimers (timers.js:268:5)
(node:6535) 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)

How can I handle this error?, if I refresh the page manually everything works fine. Thanks

Share Improve this question edited Sep 18, 2019 at 10:04 Dan Raymond asked Sep 16, 2019 at 12:13 Dan RaymondDan Raymond 1431 gold badge1 silver badge6 bronze badges 5
  • I looks like you puppeteer "page" is crashing on the "catch" portion, and you don't have another "try...catch" inside it. Try to handle this error. Sometimes puppeteer itself crashes, chromium crashes, etc... so you have to handle those errors too. For example, you can close the page (or browser) and create another page (or browser). – lcrespilho Commented Sep 16, 2019 at 12:24
  • Ok, I can try this, but how can I know the system crashed, I mean my try and catch didnt work, so try and catch the entire loop? – Dan Raymond Commented Sep 16, 2019 at 13:01
  • I would to try...catch inside the catch, just to issue the "await page.reload(page)" command, since I think it is causing the issue. But try...catch the while() with the browser creation can be better. – lcrespilho Commented Sep 16, 2019 at 14:48
  • I tried try and catch the while loop didnt solve the problem I will try what you suggested – Dan Raymond Commented Sep 16, 2019 at 15:44
  • 1 You want await page.reload();, passing page as an option doesnt make sense. You may want to have a look for reload docs and options – Maurice Meyer Commented Sep 16, 2019 at 16:44
Add a comment  | 

2 Answers 2

Reset to default 19

You are assuming, that the error happened because the page navigation failed. This might be the case, but it could also be a different error like a Protocol error. In a case like that, you cannot just reuse the page object, but you first have to restart the browser.

Some time ago, I crawled roughly 400k pages for testing purposes. In total, I experienced 34 of these puppeteer crashes, where some unexpected error crashes the whole browser. To harden your code against these kind of crashes, you need a robust way to restart the browser.

Code Sample

let browser = await puppeteer.launch(/* .. */);
let page = await browser.newPage();

while(true) {
    try {
        // your code that might crash
    } catch (err) {
        try {
            await page.reload(); // soft fix
        } catch (recoveringErr) {
            // unable to reload the page, hard fix
            try {
                await browser.close();
            } catch (err) { // browser close was not necessary
                // you might want to log this error
            }
            browser = await puppeteer.launch(/* .. */);
            page = await browser.newPage();
        }
    }
}

Although this code might look horrendous with three nested try..catch blocks, it does a good job of keeping your code running.

First, your original code is executed. If the initial problem happens, a page.reload call is tried to fix the problem. In case this works, the loop will continue running. If that does not work, the browser will be restarted.

For restarting the browser, I recommend to first try to close the old browser. Although, this might likely fail, it clears all memory and correctly disposes the browser object. Depending on your use case, you might want to log the error or simply ignore it. After disposing the old browser object, you can restart the browser and the loop may continue.

Alternative

As an alternative, you could use my library puppeteer-cluster which has error handling build in. The library automatically restarts the browser in cases in which the page is not usable anymore. In addition, the library can run multiple pages in parallel (as you are trying to stress-test the server I'm assuming).

As per the official documentation, an 'error' event is emitted when the page crashes which can be used to do certain stuff basis the application.

page.on('error', err => { /*custom logic to handle the crash*/ });

For the above specific use case, you could go about doing something like this:

let browser = await puppeteer.launch();
let page = await getNewPage(browser);

while(true){
        try{
            if (page.isClosed()) {
              page = await getNewPage(browser);
            }
            await page.waitFor(selector)
            await page.click(selector)    
        }
        catch(error){
            console.log("FE error with\n\n" + error + "\n\nRefreshing page and continuing profile switching")
            await page.reload();
            continue;
        }}


async function getNewPage(browser) {
    let page = await browser.newPage();
    page.on('error', err => {
        if (!page.isClosed()) {
            //Close page if not closed already
            page.close();
        }
    }
    return page;
}

Reference: page.on('error')

发布评论

评论列表(0)

  1. 暂无评论