puppeteer: puppeteer screenshot running on aws lambda crashes when encountering large image on site

Steps to reproduce

Tell us about your environment:

  • Puppeteer version: 1.12.2
  • Platform / OS version: aws lambda
  • URLs (if applicable):
  • Node.js version: 8.10
  • Lambda memory size: 3gb (with 30 sec timeout)

What steps will reproduce the problem?

const chromium = require('chrome-aws-lambda');
const puppeteer = require('puppeteer-core');

const SCREENSHOT_WIDTH = 1200;
const SCREENSHOT_HEIGHT = 808;

exports.handler = async (event, context, callback) => {
  let url = '';
  let tokenHash = '';

  if (event.queryStringParameters) {
    if (event.queryStringParameters.url) {
      url = event.queryStringParameters.url;
    }

    if (event.queryStringParameters.t) {
      tokenHash = event.queryStringParameters.t;
    }
  }

  let browser = null;
  let rawScreenshot = null;
  try {

    browser = await puppeteer.launch({
      args: chromium.args,
      executablePath: await chromium.executablePath,
      headless: chromium.headless,
    });
    
    const page = await browser.newPage();
    await page.setViewport({ width: SCREENSHOT_WIDTH, height: SCREENSHOT_HEIGHT });
    await page.goto(url, {});
  
    rawScreenshot = await page.screenshot({});
    await page.close();

  } catch (e) {
    console.log('token hash: ' + tokenHash);
    console.log(e);

    callback(null, {
      statusCode: 500,
      body: e.message,
      headers: {
        'Content-Type': 'text/plain',
      },
    });
  } finally {
    if (browser !== null) {
      await browser.close();
    }
  }

  callback(null, {
    statusCode: 200,
    isBase64Encoded: true,
    body: rawScreenshot.toString('base64'),
    headers: {
      'Content-Type': 'image/png',
    },
  });
};
  1. I deploy my function to AWS lambda and I invoke it with the url param
  2. sample site I’m using https://bluelitephotography.myportfolio.com

What is the expected result? A screenshot being returned

What happens instead? I consistently get the following error:

Protocol error (Page.captureScreenshot): Target closed.

Notice the 4.5 mb image being loaded on that page. The same code return screenshot successfully with most other websites.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 15 (1 by maintainers)

Most upvoted comments

To add more information: We’ve been running Puppeteer on Lambda (Node 10.x runtime) using chrome-aws-lambda with the default settings (and others while debugging, nothing worked).

When rendering HTML with an image with the following information, the browser process dies. image

With dumpio: true, we get:

[0311/213822.151939:FATAL:memory.cc(22)] Out of memory. size=155545600

What’s odd is the Lambda is configured to the maximum 3008MB. The ~155MB mentioned above is significantly less than that, and I don’t believe our Node service is using up the rest of it.

Any ideas of limits that may be not allowing Chromium to use all of the Lambda memory?

@amazd Tab crashes, most likely running out of memory. I don’t think we can do much about it on the puppeteer side; running chrome in a constrained environment is an art by itself.

I’d start with https://github.com/alixaxel/chrome-aws-lambda - a well-maintained and actually used by folks in production. There are also many more articles on the Web that might be helpful.

Hope this helps.

OP here, I was never able to fix the issue. In our case we came up with a hack, since we had access to the sites we were taking a screenshot of, we just made the photos load in lower resolution when the site detected puppeteer was taking a screenshot 😃

Was hoping this was something the puppeteer team could look more into