undici: The "event" argument must be an instance of Event. Received an instance of Event (WebSocket + ws)

Bug Description

When Undici calls fireEvent with the MessageEvent received from the server constructed via the ws package, the following error is thrown by internals/event_target:

The "event" argument must be an instance of Event. Received an instance of Event

Reproducible By

import { WebSocketServer } from 'ws'
import { WebSocket } from 'undici'

const server = new WebSocketServer({ host: '127.0.0.1', port: 0 })
server.on('connection', (client) => {
  client.on('message', (data) => {
    client.send('greetings')
  })
})

const ws = new WebSocket(server.address())
ws.addEventListener('open', () => {
  ws.send('hello')
})
ws.addEventListener('message', (event) => {
  ws.send('client received:', event.data)
})

Expected Behavior

The MessageEvent dispatched via fireEvent does not throw an error.

Logs & Screenshots

Screenshot 2024-01-29 at 14 25 25

Environment

os: MacOS 14.2.1 (23C71)
node: v18.17.0

Additional context

Here’s the check that Node performs before throwing that error:

https://github.com/nodejs/node/blob/64c6d97463c29bade4d6081683dab2cd7cda298d/lib/internal/event_target.js#L751

I suspect that the MessageEvent provided by the ws package doesn’t extend the global Event correctly, and thus fails the instanceof check. I still think it’s worth opening the issue in Undici for discoverability even if the root cause will end up to be elsewhere.

About this issue

  • Original URL
  • State: closed
  • Created 5 months ago
  • Comments: 19 (9 by maintainers)

Most upvoted comments

Can you please share a minimal test case? The one in the issue description works correctly. https://github.com/websockets/ws/issues/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.

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.