-
-
Notifications
You must be signed in to change notification settings - Fork 534
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(setupServer): suppress "ERR_INVALID_ARG_TYPE" (AbortSignal) errors from "setMaxListeners" in jsdom #1779
fix(setupServer): suppress "ERR_INVALID_ARG_TYPE" (AbortSignal) errors from "setMaxListeners" in jsdom #1779
Conversation
Hey, @christoph-fricke. Thanks so much for working on this! The test you've added doesn't fail if I remove the fix on Node.js 18.14.2. What version of Node.js are you using when you're reproducing this? |
Hey @kettanaito, it has been quite fun to do a deep dive into this problem and the Node.js source code to try and find better solution for identifying Node.js abort signals. The experience alone has justified the effort. ;) I am currently using the latest LTS version, i.e. v18.18.2. However, I wasn't able to run the added tests here due to |
@christoph-fricke, I still can't reproduce this issue even on Node.js 18.18.2.
This may be the pickle here. Afaik, Vitest uses Happy-DOM, which may differ from JSDOM. I do plan on migrating to Vitest once 2.0 is out, I love that framework and a couple of my other projects are already using it to great success. Perhaps the issue will be reproducible then. But, to be fair, I don't mind more aggressive safe-guarding around this. Developers shouldn't suffer due to the way their test environment polyfills Node.js globals (this phrase make me very sad). |
Not even with the reproduction repo? |
btw, Vitest by default uses neither I observed the problem for both |
5ae4706
to
c1f6b7e
Compare
@luchsamapparat, I can reproduce the issue in your repo. Thanks for putting that together. Caused by: TypeError: The "eventTargets" argument must be an instance of EventEmitter or EventTarget. Received an instance of AbortSignal
❯ EventEmitter.setMaxListeners node:events:326:17
❯ SetupServerApi.<anonymous> node_modules/msw/lib/node/index.mjs:51:7
❯ node_modules/msw/lib/node/index.mjs:18:61
❯ __async node_modules/msw/lib/node/index.mjs:2:10
❯ _Emitter.<anonymous> node_modules/msw/lib/node/index.mjs:50:44
❯ emitAsync node_modules/@mswjs/interceptors/lib/node/chunk-YQGTMMOZ.mjs:50:20
❯ node_modules/@mswjs/interceptors/lib/node/interceptors/fetch/index.mjs:59:35 |
* which won't be printed anyway if `setMaxListeners` fails. | ||
*/ | ||
if ( | ||
!(isNodeException(error) && error.code === 'ERR_INVALID_ARG_TYPE') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@christoph-fricke, I'm adding a more narrow condition here so we don't suppress all the thrown errors (those are still useful!).
When this particular error happens, Node.js throws an ERR_INVALID_ARG_TYPE
error code
. Let's depend on that and ignore only it.
I can verify that this change fixes the reported issue: ✓ src/index.test.ts (1)
✓ example |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good from my side. Let's wait for the CI and merge this.
Thanks for working on this! Looks like it was quite dive into the Node code base 🤿 |
This PR adds a fix for the runtime error in JSDOM that has been reported by @luchsamapparat in this comment.
Node.js
setMaxListeners
checks whether or not the given event target is a Node.jsEventTarget
(implementation) and throws an error otherwise. This check is done through an internally definedSymbol("kIsNodeEventTarget")
(implementation), so JSDOM and Happy-DOM are not able to implement it in their patchedEventTarget
.However, the main reason for calling
setMaxListeners
(see #1765) in the first place is to prevent memory-leak warnings printed by Node.js. The good thing is that the functionality for this also relies on a Node.js internalSymbol('events.maxEventTargetListenersWarned')
(implementation). Therefore, Node.js just won't print memory-leak warnings if theAbortSignal
is not based on Node.jsEventTarget
. We simply don't have to increase the max listeners warnings in JSDOM environment, since it will just not have warning problems.Since the implementations of
AbortSignal
differ mostly in internally defined Node.js symbols, we are also not able to differentiate them - at least I found no solution. The best I found is a simpletry/catch
. Please let me know if you find a better solution than the one proposed in this PR.