Puppeteer: How can I verify if the browser instance is active and accessible?

I’m attempting to maintain multiple tabs within a single instance of a browser. Once the tabs have finished their tasks, I close them and re-open them every few seconds without closing the main browser. This way, I don’t need to log in again for each tab every time. However, I want to ensure that the main browser stays open while the tabs are opened and closed as needed.

Here’s a simplified version of my code, please overlook any syntax mistakes:

let browserInstance = null;

async function setupPuppeteer(configurations) {
    if (browserInstance === null) {
        browserInstance = await puppeteer.launch({ headless: false, args: ['--no-sandbox'] });
    }
    for (let config of configurations) {
        openNewTab(config);
    }
}

async function openNewTab(config) {
    const newPage = await browserInstance.newPage();
    // perform actions on the page
    newPage.close();
}

setInterval(() => {
    setupPuppeteer(settings);
}, 50000);

Here’s the issue I’m encountering: Occasionally, the browser crashes or closes for some reason, yet the browserInstance still holds the Puppeteer object. As a result, when I try to open a new tab using that instance, I receive an error like this:

(node:5720) UnhandledPromiseRejectionWarning: Error: WebSocket is not open: readyState 3 (CLOSED)

My question is, how can I verify that I have a functioning and open instance of Puppeteer in browserInstance? I wish to create a new instance and replace it if the existing one is no longer usable.

To ensure your Puppeteer browser instance is active, you can add a simple check before attempting to open new tabs.

Here’s how you can maintain the integrity of your browserInstance:

let browserInstance = null;

async function setupPuppeteer(configurations) {
    if (!browserInstance || !(await isBrowserConnected())) {
        browserInstance = await puppeteer.launch({ headless: false, args: ['--no-sandbox'] });
    }
    for (let config of configurations) {
        openNewTab(config);
    }
}

async function isBrowserConnected() {
    try {
        // If the browser is already closed, this will throw an error
        const pages = await browserInstance.pages();
        return pages.length > 0;
    } catch (error) {
        return false;
    }
}

async function openNewTab(config) {
    const newPage = await browserInstance.newPage();
    // perform actions on the page
    await newPage.close();
}

setInterval(() => {
    setupPuppeteer(settings);
}, 50000);

Explanation:

  • isBrowserConnected() Function: It attempts to retrieve the pages from the browserInstance. If it’s closed, it will catch an error, indicating that the browser is no longer active, hence you’ll need to launch a new instance.

This approach ensures that your automation flow remains uninterrupted even if the browser crashes or closes unexpectedly.

To verify if your Puppeteer browserInstance is still active, you can check both the WebSocket connection and for any open pages, preventing errors when the browser unintentionally closes. Here’s a concise solution:

let browserInstance = null;

async function setupPuppeteer(configurations) {
    if (!browserInstance || !(await isBrowserActive())) {
        browserInstance = await puppeteer.launch({ headless: false, args: ['--no-sandbox'] });
    }
    for (let config of configurations) {
        await openNewTab(config);
    }
}

async function isBrowserActive() {
    try {
        return browserInstance.isConnected() && (await browserInstance.pages()).length > 0;
    } catch (error) {
        return false;
    }
}

async function openNewTab(config) {
    const newPage = await browserInstance.newPage();
    await newPage.close();
}

setInterval(() => {
    setupPuppeteer(settings);
}, 50000);

Key Points:

  • isBrowserActive() Function: Checks the WebSocket connection with isConnected() and verifies open pages to ensure the instance is truly active.

To further verify if the browserInstance is functioning properly, you can enhance your approach by explicitly checking the browser’s WebSocket connection status. This method not only checks for open pages but also ensures that the connection is alive. Here’s how you can implement this check:

let browserInstance = null;

async function setupPuppeteer(configurations) {
    if (!browserInstance || !(await isBrowserActive())) {
        browserInstance = await puppeteer.launch({ headless: false, args: ['--no-sandbox'] });
    }
    for (let config of configurations) {
        await openNewTab(config);
    }
}

async function isBrowserActive() {
    try {
        if (!browserInstance.isConnected()) {
            return false;
        }
        // Additional check to verify pages
        const pages = await browserInstance.pages();
        return pages.length > 0;
    } catch (error) {
        return false;
    }
}

async function openNewTab(config) {
    const newPage = await browserInstance.newPage();
    // perform actions on the page
    await newPage.close();
}

setInterval(() => {
    setupPuppeteer(settings);
}, 50000);

Explanation:

  • isBrowserActive() Function: This function first checks the WebSocket connection status using browserInstance.isConnected(). If the connection is not active, it indicates that the browser needs to be relaunched.
  • The function then proceeds to check whether the browser can retrieve any open pages. This additional check ensures robustness as it covers scenarios where the connection might be technically open but non-functional.

By incorporating these checks, you can better manage your Puppeteer instances, ensuring they are truly active and ready to use, thus preventing errors resulting from unexpected browser closures.

To ensure your Puppeteer browserInstance remains active and functional, you can implement a two-step verification process for the browser's connectivity and accessibility. Here’s how you can keep your automation flow robust:

let browserInstance = null;

async function setupPuppeteer(configurations) {
    if (!browserInstance || !(await isBrowserInstanceActive())) {
        browserInstance = await puppeteer.launch({ headless: false, args: ['--no-sandbox'] });
    }
    for (let config of configurations) {
        await openNewTab(config);
    }
}

async function isBrowserInstanceActive() {
    try {
        return browserInstance.isConnected() && (await browserInstance.pages()).length > 0;
    } catch (error) {
        return false;
    }
}

async function openNewTab(config) {
    const newPage = await browserInstance.newPage();
    await newPage.close();
}

setInterval(() => {
    setupPuppeteer(settings);
}, 50000);

Explanation:

  • isBrowserInstanceActive() Function: This function first uses isConnected() to ensure the WebSocket connection is live. It also checks for any open pages by calling browserInstance.pages(). If both checks pass, you can confidently use the instance.
  • This approach efficiently manages your browser instance, ensuring minimal downtime even if the browser crashes unexpectedly.

By systematically checking both the connectivity and availability of open pages, you maintain a reliable Puppeteer setup that continues to function smoothly even during unforeseen closures.