websockets/ws TypeError

I’m getting an error from websockets/ws:

/root/diag/node_modules/ws/lib/WebSocket.js:422
    event.target = target;
                 ^
TypeError: Cannot assign to read only property 'target' of reserved fields (2, 3) must be empty
    at WebSocket.onError (/root/diag/node_modules/ws/lib/WebSocket.js:422:18)
    at WebSocket.emit (events.js:110:17)
    at Receiver.onerror (/root/diag/node_modules/ws/lib/WebSocket.js:832:10)
    at Receiver.error (/root/diag/node_modules/ws/lib/Receiver.js:317:8)
    at Receiver.processPacket (/root/diag/node_modules/ws/lib/Receiver.js:186:12)
    at Receiver.add (/root/diag/node_modules/ws/lib/Receiver.js:91:24)
    at firstHandler (/root/diag/node_modules/ws/lib/WebSocket.js:767:22)
    at process._tickCallback (node.js:355:11)

This is not referring to any specific line in my code, so I don’t even know where in my code is causing this.

Is this a bug with the new update of module or am I doing something wrong?

I haven’t updated the websocket client (which is where the error is coming from) in a while.

EDIT

The websocket is used at two different locations:

// main file that then passes socket to libdiag.js
socket.on('connect', function () {
    socket.emit('authenticate', {
        method: 'token',
        credentials: token
    });
});

socket.on('authenticate', function(packet) {
    var data = JSON.parse(packet.data);
    if (packet.channel == CHANNEL && data.status == "authenticated") {
        libdiag.start(socket, CHANNEL);
    }
});

socket.on('disconnect', function () {
    start();
});

socket.on('error', function (err) {
    libdiag.error(err); // This is just a logger that writes to file
});

And this file

// This is libdiag.js
socket.on('data', function (packet) {
    var data = JSON.parse(packet.data);

    // New listener is requesting handshake
    if (packet.type == SOCKET_HANDSHAKE) {
        _handshake(data);
    }

    // A listener has left
    if (packet.type == SOCKET_CLOSED) {
        _listenerLeft(data);
    }

    if (packet.type == SOCKET_UPDATE) {
        _read(data);
    }
});

socket.on('disconnect', function () {
    libdiag.destroy(); // This calls socket.disconnect() and sets the variables to null
});

Answer

I believe you are trying to bind a DOM Level 2 to one of your websockets callbacks, DOM Level 2 Events have their target property set as readOnly:

// Introduced in DOM Level 2:
interface Event {

  // PhaseType
  const unsigned short      CAPTURING_PHASE                = 1;
  const unsigned short      AT_TARGET                      = 2;
  const unsigned short      BUBBLING_PHASE                 = 3;

  readonly attribute DOMString        type;
  readonly attribute EventTarget      target;
  readonly attribute EventTarget      currentTarget;
  readonly attribute unsigned short   eventPhase;
  readonly attribute boolean          bubbles;
  readonly attribute boolean          cancelable;
  readonly attribute DOMTimeStamp     timeStamp;
  void               stopPropagation();
  void               preventDefault();
  void               initEvent(in DOMString eventTypeArg, 
                               in boolean canBubbleArg, 
                               in boolean cancelableArg);
};

And it seems that in your flow, something is triggering the onError handler of the websocket, which tries to change the event.target:

function onError (event) {
    event.type = 'error';
    event.target = target;
    listener.call(target, event);
}

I believe this is the root cause of the error you are seeing there in your console. It would be helpful if you show us the code regarding on the events/callbacks/handlers you are binding or using with your websocket in order to determine a way to not use a DOM Level 2 event.

Leave a Reply

Your email address will not be published. Required fields are marked *