Skip to content

_$onError crashes Node when no 'error' listener attached; _onMessage double-emits mis-shaped errors #42

Description

@ronag

Severity: Critical
Files: src/client.js:72-91 and src/client.js:93-110

1. _\$onError throws when no listener

if (this.hasListeners('error')) { ... } else { console.log('---'); throw error }

Any hot path that calls _\$onError — malformed server message, unknown TOPIC, unknown action, parse failure — throws synchronously out of the websocket onmessage handler when the user hasn't attached an error listener. In Node this terminates the process. A hostile (or buggy) server can crash every connected client.

Examples that hit this path: message-parser.js:53 (< 2 parts), message-parser.js:67 (unknown action), any _\$onError from topic handlers.

2. _onMessage double-emits + wrong signature

if (this._messageCallbacks[message.topic]) {
  try { this._messageCallbacks[message.topic](message) } catch (err) {
    this._\$onError(message.topic, null, err, message.data.slice(0))
  }
} else {
  this._\$onError(message.topic, C.EVENT.MESSAGE_PARSE_ERROR, )
}
if (message.action === C.ACTIONS.ERROR && !message.processedError) {
  this._\$onError(message.topic, message.data[0], message.data.slice(0))
}
  • The handled branch never sets processedError = true. If the handler's callback returns false (common — e.g. RECORD ERROR for an unregistered record), the trailing if (message.action === ERROR) re-fires _\$onError for the same message.
  • The second call uses signature (topic, data[0], data.slice(0)) but _\$onError(topic, event, msgOrError, data) expects data as the 4th arg — so data is always undefined. Produces mis-shaped error objects.
  • _onErrorMessage (line 112) has the same signature mismatch: passes errorMessage.data[1] as msgOrError when it's often just a secondary token.

Suggested fix

  • Don't throw from _\$onError. Log via console.error (Node) or emit on process (uncaughtException) as a last resort, but never throw out of a WS onmessage.
  • In _onMessage: set processedError appropriately, return after handling, and align call signatures.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions