0
  1. In nodejs Rest api call, puppeteer page evaluate not returning the response and throws the error.
  2. How to return object after executing all the steps, without async
app.get("/api/register", function (req, res) {
 
  res =  page.evaluate((res) => {
    
   
      webex.meetings
        .register()
        .then(() => {
          console.log("Authentication#register() :: successfully registered");
         return res.status(200).json({ message: "Successfully Registered" });
        })
        .catch((error) => {
          console.error( "Authentication#register() :: error registering", error);
       return   res.status(400).json({ message: "Successfully Registered" });
        })
        
   
  }, res);
});

error :\Users\sansubbu\git\webRTC\node_modules\puppeteer-core\lib\cjs\puppeteer\common\Connection.js:115 const stringifiedMessage = JSON.stringify(Object.assign({}, message, { id })); ^

TypeError: Converting circular structure to JSON --> starting at object with constructor 'Socket' | property 'parser' -> object with constructor 'HTTPParser' --- property 'socket' closes the circle Recursive objects are not allowed. at JSON.stringify () at Connection._rawSend (C:\Users\sansubbu\git\webRTC\node_modules\puppeteer-core\lib\cjs\puppeteer\common\Connection.js:115:41) at CDPSessionImpl.send (C:\Users\sansubbu\git\webRTC\node_modules\puppeteer-core\lib\cjs\puppeteer\common\Connection.js:320:82) at ExecutionContext._ExecutionContext_evaluate (C:\Users\sansubbu\git\webRTC\node_modules\puppeteer-core\lib\cjs\puppeteer\common\ExecutionContext.js:211:46)

santhosh
  • 1
  • 6
  • Not sure what you're trying to do, but `res` is not going to work inside an `evaluate` call. Return a promise from your `webex.meetings().register` and `await` it in Node land, then call `res`, or use `page.exposeFunction` to enable triggering `res.json()` from the browser. – ggorlen Nov 09 '22 at 15:42

1 Answers1

0

res is a complex, circular structure that only works in the Node environment. Even if you could, passing it to the browser console via page.evaluate() would take it out of Node, where it belongs, leaving it in an environment where it doesn't make any sense (browsers can't respond to requests as if they were a server).

Instead, try returning a boolean and branching on that on the Node side, where req/res are in their natural environment:

app.get("/api/register", async (req, res) => {
  const success = await page.evaluate(async () => {
    try {
      await webex.meetings.register();
      return true;
    }
    catch (err) {
      return false;
    }
  });

  if (success) {
    console.log("Authentication#register() :: successfully registered");
    return res.status(200).json({message: "Successfully Registered"});
  }

  console.error("Authentication#register() :: error registering", error);

  // probably not the message you want but left as-is...
  return res.status(400).json({message: "Successfully Registered"});
});

This is untested since you haven't provided a complete, reproducible example.

page.exposeFunction is another possible tool for triggering Node code based on a condition in the browser, but that seems like overkill here.

Finally, I'm not sure what page is, but typically you need a different page for each request. See this answer for suggested Express + Puppeteer boilerplate.

ggorlen
  • 44,755
  • 7
  • 76
  • 106