puppeteer-extra: [Bug] unhandledRejection (Target.attachToTarget)

Describe the bug

Hey there, reproducing my code snippet will lead to an unhandledRejection.

It basically opens a Browser instance and closes it before creating a new page, therefore, it fails as expected. The problem is that the error is not correctly catched.

If I reproduce the same code snippet commenting puppeteer.use(pluginStealth()), the error will be correctly catched so I guess the problem comes from puppeteer-extra rather than from puppeteer itself.

Code Snippet

const puppeteer = require('puppeteer-extra')
const pluginStealth = require('puppeteer-extra-plugin-stealth')

puppeteer.use(pluginStealth())

puppeteer.launch({
	headless: false,
	args: [
		'--window-position=0,0',
		'--disable-infobars',
		'--disable-extensions',
		'--disable-accelerated-2d-canvas',
		'--disable-gpu',
		'--window-size=1920x1080',
		'--disable-dev-shm-usage',
		'--disable-setuid-sandbox',
		'--no-first-run',
		'--no-sandbox',
		'--no-zygote',
		'--single-process',
		'--deterministic-fetch',
		'--enable-features=NetworkService',
		'--ignore-certificate-errors'
	]
})
.then((browser) => {
    browser.close()

	return browser.newPage()
})
.catch((err) => {
    console.log(err)
})

What is happening

(node:18424) [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.
(node:18424) UnhandledPromiseRejectionWarning: Error: Protocol error (Target.attachToTarget): No target with given id found
    at C:\Users\xxxx\Desktop\lol\node_modules\puppeteer\lib\cjs\puppeteer\common\Connection.js:71:63
    at new Promise (<anonymous>)
    at Connection.send (C:\Users\xxxx\Desktop\lol\node_modules\puppeteer\lib\cjs\puppeteer\common\Connection.js:70:16)
    at Connection.createSession (C:\Users\xxxx\Desktop\lol\node_modules\puppeteer\lib\cjs\puppeteer\common\Connection.js:141:42)
    at Target._sessionFactory (C:\Users\xxxx\Desktop\lol\node_modules\puppeteer\lib\cjs\puppeteer\common\Browser.js:178:91)
    at Target.page (C:\Users\xxxx\Desktop\lol\node_modules\puppeteer\lib\cjs\puppeteer\common\Target.js:72:38)
    at Plugin._onTargetCreated (C:\Users\xxxx\Desktop\lol\node_modules\puppeteer-extra-plugin\dist\index.cjs.js:489:39)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
(node:18424) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)

What should happen

Error: Protocol error (Target.attachToTarget): No target with given id found
    at C:\Users\xxxx\Desktop\lol\node_modules\puppeteer\lib\cjs\puppeteer\common\Connection.js:71:63
    at new Promise (<anonymous>)
    at Connection.send (C:\Users\xxxx\Desktop\lol\node_modules\puppeteer\lib\cjs\puppeteer\common\Connection.js:70:16)
    at Connection.createSession (C:\Users\xxxx\Desktop\lol\node_modules\puppeteer\lib\cjs\puppeteer\common\Connection.js:141:42)
    at Target._sessionFactory (C:\Users\xxxx\Desktop\lol\node_modules\puppeteer\lib\cjs\puppeteer\common\Browser.js:178:91)
    at Target.page (C:\Users\xxxx\Desktop\lol\node_modules\puppeteer\lib\cjs\puppeteer\common\Target.js:72:38)
    at Plugin._onTargetCreated (C:\Users\xxxx\Desktop\lol\node_modules\puppeteer-extra-plugin\dist\index.cjs.js:489:39)
    at processTicksAndRejections (internal/process/task_queues.js:93:5) {
  message: 'Protocol error (Target.attachToTarget): No target with given id found'
}

Versions

System: OS: Windows 10 10.0.19042 CPU: (6) x64 Intel® Core™ i5-8400 CPU @ 2.80GHz Memory: 4.24 GB / 7.92 GB Binaries: Node: 12.13.1 - C:\Program Files\nodejs\node.EXE npm: 6.12.1 - C:\Program Files\nodejs\npm.CMD

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 19 (3 by maintainers)

Most upvoted comments

Hey again, thanks for this awesome answers, I already tested a similar solution using process.on(“unhandledRejection”… previously

It seems that it is catching some of the unhandledRejections but still throws a node error sometimes, I’m going to give it another shot using @clouedoc solution.

I’m running a 5m+ various headless requests a day so I have enough data to sort this out quickly, I’ll give you an update on this in a couple of days.

Thanks again!

This should now be fixed through #555:

Successfully published:
 - puppeteer-extra-plugin-adblocker@2.12.0
 - puppeteer-extra-plugin-anonymize-ua@2.3.0
 - puppeteer-extra-plugin-block-resources@2.3.0
 - puppeteer-extra-plugin-click-and-wait@2.3.0
 - puppeteer-extra-plugin-devtools@2.3.0
 - puppeteer-extra-plugin-flash@2.3.0
 - puppeteer-extra-plugin-font-size@2.3.0
 - puppeteer-extra-plugin-recaptcha@3.5.0
 - puppeteer-extra-plugin-repl@2.3.0
 - puppeteer-extra-plugin-stealth@2.8.0
 - puppeteer-extra-plugin-user-data-dir@2.3.0
 - puppeteer-extra-plugin-user-preferences@2.3.0
 - puppeteer-extra-plugin@3.2.0
 - puppeteer-extra@3.2.0

I’m not using async await but exclusively promises, I did not manage to fix the issues yet, the stack trace still show that the error comes from /puppeteer/lib/Connection.js that is called by /puppeteer-extra-plugin/dist/index.cjs.js so I’m almost sure it does not come from my code.

My real interrogation is how the heck is it possible to still have those warnings after putting:

process.on('uncaughtException', (err) => {
    	return
})
    
process.on('unhandledRejection', (reason, promise) => {
        return
 })

In the very begining of my app.js in a basic express model/route/controller app ^^

Thanks for the support anyways, I will keep you in touch once I realize why.

@clouedoc so is the code you’ve posted working for you? 😃

I tested the code and I can confirm that it does the following:

  1. Catches the unhandled session/target errors
  2. Warns me about them without crashing the process
  3. Still throws other unhandled promise rejections

I would say that yes, it works. Feel free to point it out if you’ve found something odd in it 😉!

To quote myself here from our discord channel:

hmm, that’s not necessarily a fatal error - it’s more of an FYI that the Target closed while still being worked with that can happen if a page is navigated/closed immediately after loading as for why that happens only with the stealth plugin enabled (presumably): The plugin will do a bunch of things with a page, so the chance of this happening is enlarged look into handleUncaughtExceptions handlers if you want to suppress these messages (in case they don’t affect your business logic)

keep in mind that it’s best practice to selectively check for errors you want to supress and rethrow the rest in these global handlers: https://nodejs.org/api/process.html#process_event_uncaughtexception

Another user suggests to explicitly close the page before closing the browser to mitigate this issue.

Yet another user mentioned launching with a '--disable-dev-shm-usage' flag improved this behavior.

TL;DR: This is not really a bug but relatively normal behavior.

If you want to suppress those errors (or make them non-fatal) use a global catch handler (make sure to selectively mute errors there though):

// untested but something along these lines should work
process.on('uncaughtException', (err, origin) => {
  const isTargetClosedError = err?.message.includes('Protocol error (Target.attachToTarget): No target with given id found')
  if (isTargetClosedError) {
    console.log('Caught TargetClosedError', err)
  } else {
    throw err // Re-throw all other errors
  }
});

See here for how common that issue is: https://stackoverflow.com/a/51989560

Closing this unless there’s clear/specific evidence that extra or stealth has a bug in this regard that needs fixing.

edit, you might need to use a unhandledRejection handler for this