Comments (19)
But you are adding it to the the undici WebSocket
instance, not ws WebSocket
instance. You are not using ws event-target.js
at all in the example.
from undici.
Can you please share a minimal test case? The one in the issue description works correctly. websockets/ws#1818 has nothing to do with this unless you take a ws
Event
and manually dispatch it with undici
's WebSocket
which does not make sense to me.
from undici.
Closing because it's the issue in the ws
package (see websockets/ws#1818 (comment)).
I suspect that due to the Node.js version support they promise, they ended up re-implementing Event
and EventTarget
, which leads to the MessageEvent extends Event
extending the wrong Event
(their own, not the global one; see https://github.com/websockets/ws/blob/5e42cfdc5fa114659908eaad4d9ead7d5051d740/lib/event-target.js#L17).
from undici.
Strangely, even if I modify ws
to dispatch a global Event
, its instanceof
check still returns false
, even if inlined in Undici's fireEvent
. Can the two packages be getting different global Event
object? 🤔
from undici.
I don't understand. In the example ws
does not fire any event. The event is fired by undici
. What ws
sends to undici is just a WebSocket frame.
from undici.
@lpinca ws
sends an Event
instance (i.e. the new Event('open')
), which undici
then provides to fireEvent
, triggers dispatchEvent
of the Node's native EventTarget
, and the error is thrown. Perhaps I should've stressed that this is what happens under the hood.
from undici.
Here's a detailed call stack:
ws
implicitly constructs an openEvent
whenthis.emit('open')
is called (maps back the emitter interface to the event target call signature): https://github.com/websockets/ws/blob/5e42cfdc5fa114659908eaad4d9ead7d5051d740/lib/event-target.js#L234- The open event bubbles to
undici
, and undici provides it tofireEvent
, then totarget.dispatchEvent
.Line 42 in b04d65c
internal/event_target.js
checks whether the dispatched event is an instance ofEvent
. If not, it throws (https://github.com/nodejs/node/blob/64c6d97463c29bade4d6081683dab2cd7cda298d/lib/internal/event_target.js#L751). In case ofws
it will never pass this check becausews
implements its ownEvent
and derived classes to (MessageEvent
,CloseEvent
,ErrorEvent
).
At its core, it's class identity issue (ws
re-implementing Event
). But as I've stated above, even if I patch ws
and drop event-target.js
from it entirely, the events that arrive at Undici still fail the instanceof
check. Most likely me patching things wrong.
from undici.
There is no listener for the 'open'
event in the example.
from undici.
@lpinca there's a listener for the message
event though. The same thing happens to all events from ws
(open, message, error, close) since none of them extend the global Event
in Node. The ws
module cannot be used with the WebSocket
class from undici
at its current state.
from undici.
I apologize, I extracted my issue scenario incorrectly 👍 Will update to prevent further confusion.
from undici.
I don't see how this is related to ws
. If there is an issue it's in undici. @KhafraDev
from undici.
the repro works fine for me, is there an example where it doesn't?
from undici.
I think they are doing something like websockets/ws#1818 but I see nothing related to ws
in the stack trace.
from undici.
error is coming from:
function fireEvent (e, target, eventConstructor = Event, eventInitDict) {
const event = new eventConstructor(e, eventInitDict) // eslint-disable-line new-cap
target.dispatchEvent(event)
}
fireEvent('open', <websocket instance>)
I can only see this being an issue if Event is being overridden (a la jest). I don't think this is an undici issue either without more info.
from undici.
@KhafraDev, like I suspected, this isn't an issue with Undici. It simply surfaces through it.
The issue is in the ws
module (see websockets/ws#1818).
from undici.
Since ws' Event is similar to the spec one, it should be possible to take the attributes from ws' Event and create a node Event from that.
from undici.
Reproduction case
- Check out mswjs/interceptors#501.
- Open
test/modules/WebSocket/exchange/websocket.server.connect.test.ts
. Uncomment any/all server tests. pnpm test test/modules/WebSocket/exchange/websocket.server.connect.test.ts
See the following errors during the test run:
TypeError: The "event" argument must be an instance of Event. Received an instance of Event
❯ new NodeError ../node:internal/errors:405:5
❯ WebSocket.dispatchEvent ../node:internal/event_target:678:13
❯ fireEvent ../node_modules/.pnpm/[email protected]/node_modules/undici/lib/websocket/util.js:58:10
❯ WebSocket.#onConnectionEstablished ../node_modules/.pnpm/[email protected]/node_modules/undici/lib/websocket/websocket.js:537:5
❯ ../node_modules/.pnpm/[email protected]/node_modules/undici/lib/websocket/websocket.js:126:50
❯ Object.processResponse ../node_modules/.pnpm/[email protected]/node_modules/undici/lib/websocket/connection.js:197:7
❯ ../node_modules/.pnpm/[email protected]/node_modules/undici/lib/fetch/index.js:1083:38
❯ ../node:internal/process/task_queues:140:7
❯ AsyncResource.runInAsyncScope ../node:async_hooks:203:9
❯ AsyncResource.runMicrotask ../node:internal/process/task_queues:137:8
This reproduction case is a part of the Interceptors library. Note that the interceptor itself doesn't affect Event
, Undici, or ws
in any way. I can put up a more isolated repository if you wish but the instructions above will give you the errors I'm experiencing.
The test in question will produce the same error even if you remove the interceptor part from it, which leads me to believe something else is the root cause here.
More context
I learned that Undici also implements its own events but they do extend the global Event
class, which should make individual events correct instances of the global Event
.
However, that's not the case. Here's when Undici emits its own MessageEvent
:
Lines 96 to 102 in e30f200
If I check event instanceof Event
in fireEvent()
, I will get false
:
Line 48 in e30f200
console.log(event instanceof Event)
false
I'm a bit confused why this is happening even if it's my specific issue. The only case I can think of when this would happen is when the global
Error
points to different classes in Undici and in Node.js. Undici doesn't do anything to result in this. The Interceptors library also doesn't do anything to result in this. Odd.
This instance check later on results in the Node.js error during the event validation here:
I would be grateful if you point me in the right direction and explain why is that instance check failing.
from undici.
This is likely an environment problem. Standalone, Undici events pass the instanceof check:
const { MessageEvent } = require('undici/lib/websocket/events.js')
console.log(new MessageEvent('message') instanceof Event)
// true
I will try to see if this has anything to do with the test runner I'm using.
from undici.
Root cause
This error was happening due to JSDOM. It's always JSDOM. Looks like the global Event
integrity is violated when you use Jest+JSDOM. This has cost me almost a week of debugging.
Thank you everyone for help here. I appreciate it a lot.
from undici.
Related Issues (20)
- test against Node.js nightlies HOT 4
- Wasm SIMD unsupported HOT 11
- Move logic to interceptors HOT 2
- EventSource properties are not configured properly HOT 6
- test\client-request.js is consistently failing HOT 1
- TypeError: fetch failed due to ECONNREFUSED cannot be caught and handled HOT 2
- Unexpected token on class private field check with in operator HOT 21
- Option mismatch in RetryHandler HOT 2
- Uncaught TypeError: fetch failed. node:internal/deps/undici/undici:12345:11 HOT 1
- Retry with timeout HOT 7
- Is `fetch` API planned to support unix domain socket? HOT 5
- interceptors does not have any exported type HOT 1
- Nightly tests are failing HOT 1
- Can not upload file in nodejs 20 HOT 6
- [TS] Signature method of Interceptor using Dispatcher#compose HOT 4
- Fails to retrieve the first piece of data when downloading partial content with `RetryAgent` HOT 1
- Documentation/website has broken benchmark links
- Client network socket disconnected before secure TLS connection was established HOT 4
- TypeError: fetch failed - on Node v20.11.1 and v21.7.1, but works on v18.19.1 - likely issue with resolving redirect URL or IPv6 HOT 3
- BodyTimeoutError: Body Timeout Error | Closing process HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from undici.