Matt
Matt

Reputation: 8942

Puppeteer - Async function in evaluate method throws error

I am trying to check if og:image source exists. If I want to call async method in evaluate function, I get Error: Evaluation failed: [object Object] error.

    Error: Evaluation failed: [object Object]
    at ExecutionContext._evaluateInternal (.../node_modules/puppeteer/lib/ExecutionContext.js:122:13)
    at processTicksAndRejections (internal/process/task_queues.js:89:5)
    at async ExecutionContext.evaluate (.../node_modules/puppeteer/lib/ExecutionContext.js:48:12)
  -- ASYNC --
    at ExecutionContext.<anonymous> (.../node_modules/puppeteer/lib/helper.js:111:15)
    at DOMWorld.evaluate (.../node_modules/puppeteer/lib/DOMWorld.js:112:20)
    at processTicksAndRejections (internal/process/task_queues.js:89:5)
  -- ASYNC --
    at Frame.<anonymous> (.../node_modules/puppeteer/lib/helper.js:111:15)
    at Page.evaluate (.../node_modules/puppeteer/lib/Page.js:827:43)
    at Page.<anonymous> (.../node_modules/puppeteer/lib/helper.js:112:23)
    at run (/Users/andrejgajdos/devel/link-preview/app.js:195:28)
    at processTicksAndRejections (internal/process/task_queues.js:89:5)

app.sj

const puppeteer = require("puppeteer");
const util = require('util');
const urlExists = util.promisify(require('url-exists'));

const run = async () => {
  try {
    const browser = await puppeteer.launch({ headless: true });
    const page = await browser.newPage();

    await page.goto('https://www.onepeloton.com/', { waitUntil: 'domcontentloaded' });

    const img = await page.evaluate(async () => {
      const ogImg = document.querySelector('meta[property="og:image"]');
      if (ogImg != null && ogImg.content.length > 0) {
        const isExists = await urlExists(ogImg.content);
        return isExists;
      }
    });
    console.log(img);

    await browser.close()
  } catch (e) {
    console.log(e);
  }
}

run();

Upvotes: 5

Views: 8480

Answers (1)

hardkoded
hardkoded

Reputation: 21607

All the code inside the evaluate is executed on the chromium side.
As urlExists is being imported on the node side, you wouldn't be able to access to that function from the browser.

Unless you expose it using page.exposeFunction. Once you expose that function, chromium will be able to call urlExists.

const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();

await page.goto('https://www.onepeloton.com/', { waitUntil: 'domcontentloaded' });
await page.exposeFunction('urlExists', urlExists);

const img = await page.evaluate(async () => {
    const ogImg = document.querySelector('meta[property="og:image"]');
    if (ogImg != null && ogImg.content.length > 0) {
    const isExists = await urlExists(ogImg.content);
    return isExists;
    }
});
console.log(img);

await browser.close()

Upvotes: 11

Related Questions