Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aborting PDF render doesn't stop chromium immediately #1505

Closed
kodchi opened this issue Nov 30, 2017 · 8 comments
Closed

Aborting PDF render doesn't stop chromium immediately #1505

kodchi opened this issue Nov 30, 2017 · 8 comments
Labels
bug chromium Issues with Puppeteer-Chromium unconfirmed

Comments

@kodchi
Copy link

kodchi commented Nov 30, 2017

Steps to reproduce

Tell us about your environment:

  • Puppeteer version: 0.13.0
  • Platform / OS version: Arch Linux 4.13.12-1-ARCH
  • URLs (if applicable): n/a

What steps will reproduce the problem?
I'd like to abort a PDF render, but puppetteer doesn't abort immediately after closing the page and browser instances used in rendering the PDF. Here's the snippet of code that I'm using for testing:

const puppeteer = require('puppeteer');  // version 0.13.0

const puppeteerOptions = {
    timeout: 5000,
    args: [ '--no-sandbox', '--disable-setuid-sandbox']
};
const pdfOptions = {
    scale: 1,
    displayHeaderFooter: false,
    printBackground: false,
    landscape: false,
    pageRanges: '',
    format: 'Letter',
    margin: {
        top: '0.5in',
        right: '0.5in',
        bottom: '0.75in',
        left: '0.5in'
    }
};
const url = 'https://en.wikipedia.org/api/rest_v1/page/html/Hendrick_Motorsports';

let browser;
let page;

let cleanup = () => {
    if (page) {
        console.log('closing the page');
        page.close().then(() => {
            if (browser) {
                console.log('closing the browser');
                browser.close();
                browser = null;
            }
            page = null;
        });
    }
};

puppeteer.launch(puppeteerOptions)
    .then((browser_) => {
        browser = browser_;
        console.log('_1. opening a new page');
        return browser.newPage();
    })
    .then((page_) => {
        page = page_;
        console.log('_2. visiting the url');
        return page.goto(url, {
            timeout: 5000,
            waitUntil: 'networkidle2'
        });
    })
    .then(() => {
        console.log('_3. creating a pdf');
        return page.pdf(pdfOptions);
    })
    .catch((error) => {
        console.log('_4. error', error);
        cleanup();
        throw error;
    })
    .then((pdf) => {
        console.log('_5. returning pdf', pdf);
        cleanup();
        return pdf;
    });

// close the page and browser so that we can abort the request
// to create a PDF
setTimeout(cleanup, 500);

What is the expected result?
I should see the following text in the console. Italicized text is my comment.
_1. opening a new page
_2. visiting the url
closing the page
closing the browser
_4. Some kind of an error about the closed page or browser instance should be thrown immediately without waiting for timeout. It's true that I'm aborting the process in page.goto step, but aborting in any other step after creating a puppeteer instance results in the same issue: the chromium process doesn't stop immediately, rather it does what it's doing and then finish when it's done.

What happens instead?
_1. opening a new page
_2. visiting the url
closing the page
closing the browser
(about 5 second wait happens here)
_4. error Error: Navigation Timeout Exceeded: 5000ms exceeded
at Promise.then (/home/bmansurov/workspace/mediawiki-services/chromium-render/node_modules/puppeteer/lib/NavigatorWatcher.js:69:21)
at
(node:22758) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Navigation Timeout Exceeded: 5000ms exceeded
(node:22758) [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.

@LLLLLamHo
Copy link

I have the same problem

@pavelfeldman
Copy link
Contributor

I don't think you are aborting the pdf render, you are rather aborting the navigation. So as I read it, you are expecting pending requests such as goto to throw upon page.close().

@kodchi
Copy link
Author

kodchi commented Dec 6, 2017

That's correct. As I indicated at the end of the "What is the expected result?" section, the issue persists when aborting the render too.

@phuedx
Copy link

phuedx commented Dec 22, 2017

Here's a slightly shorter snippet that reproduces the issue without instructing the browser to render a PDF:

const puppeteer = require('puppeteer') // v0.13.0

const URL = 'https://en.wikipedia.org/api/rest_v1/page/html/Maybeshewill'

function gotoAndClose(browser) {
    browser.newPage()
        .then((page) => {
            console.log(`page#goto(${URL})`)

            // Defer closing the page so that navigation can start.
            process.nextTick(() => {
                console.log('page#close()')

                page.close()
                    .then(() => {
                        console.log('browser#close()')

                        // Close the browser so that the Node.js process can
                        // exit.
                        browser.close()
                    })
            })

            return page.goto(URL, {
                timeout: 5000,
                waitUntil: 'networkidle2'
            })
        })
        .catch((error) => console.log('Error: ', error))
}

puppeteer.launch()
    .then(gotoAndClose)

which yields the following output:

page#goto(https://en.wikipedia.org/api/rest_v1/page/html/Maybeshewill)
page#close()
browser#close()
# ~5 seconds later...
Error:  Error: Navigation Timeout Exceeded: 5000ms exceeded
    at Promise.then (/Users/phuedx/Public/puppeteer-issue-1505/node_modules/puppeteer/lib/NavigatorWatcher.js:69:21)
    at <anonymous>

AFAICT this is an issue with the NavigatorWatcher that's created in the Page#goto call not being notified that the connection to the Chromium process has been closed (and the process killed?). The NavigatorWatcher races a timeout against page lifecycle or frame events occurring. However, since the connection has been closed, those events won't occur and the timeout wins the race.

@polishdeveloper
Copy link

@aslushnikov - are there any plans to work on this issue? We also noticed that if we start the PDF render and then, for example, kill the Chromium instance manually - the puppeteer instance is not being notified about chromium unavailability. It keeps waiting for the response, and then after {puppeteer_options.timeout} seconds it timeouts with: Error: navigation timeout exceeded".

@aslushnikov
Copy link
Contributor

are there any plans to work on this issue?

@polishdeveloper we have a huge backlog of features to work on. We prioritize first "most wanted" features/issues, and we figure the demand from amount of "likes" on the issue.

Given this, this bug is a low-pri for us.

@aslushnikov aslushnikov added the chromium Issues with Puppeteer-Chromium label Dec 6, 2018
@stale
Copy link

stale bot commented Jun 27, 2022

We're marking this issue as unconfirmed because it has not had recent activity and we weren't able to confirm it yet. It will be closed if no further activity occurs within the next 30 days.

@stale stale bot added the unconfirmed label Jun 27, 2022
@stale
Copy link

stale bot commented Jul 27, 2022

We are closing this issue. If the issue still persists in the latest version of Puppeteer, please reopen the issue and update the description. We will try our best to accomodate it!

@stale stale bot closed this as completed Jul 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug chromium Issues with Puppeteer-Chromium unconfirmed
Projects
None yet
Development

No branches or pull requests

6 participants