Skip to content

Commit a1be71e

Browse files
authored
add cause to WebSocket error (#4274)
1 parent dbba3eb commit a1be71e

File tree

5 files changed

+30
-8
lines changed

5 files changed

+30
-8
lines changed

lib/web/websocket/connection.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ function establishWebSocketConnection (url, protocols, client, handler, options)
105105
// 1. If response is a network error or its status is not 101,
106106
// fail the WebSocket connection.
107107
if (response.type === 'error' || response.status !== 101) {
108-
failWebsocketConnection(handler, 1002, 'Received network error or non-101 status code.')
108+
failWebsocketConnection(handler, 1002, 'Received network error or non-101 status code.', response.error)
109109
return
110110
}
111111

@@ -298,9 +298,10 @@ function closeWebSocketConnection (object, code, reason, validate = false) {
298298
* @param {import('./websocket').Handler} handler
299299
* @param {number} code
300300
* @param {string|undefined} reason
301+
* @param {unknown} cause
301302
* @returns {void}
302303
*/
303-
function failWebsocketConnection (handler, code, reason) {
304+
function failWebsocketConnection (handler, code, reason, cause) {
304305
// If _The WebSocket Connection is Established_ prior to the point where
305306
// the endpoint is required to _Fail the WebSocket Connection_, the
306307
// endpoint SHOULD send a Close frame with an appropriate status code
@@ -315,7 +316,7 @@ function failWebsocketConnection (handler, code, reason) {
315316
handler.socket.destroy()
316317
}
317318

318-
handler.onFail(code, reason)
319+
handler.onFail(code, reason, cause)
319320
}
320321

321322
module.exports = {

lib/web/websocket/websocket.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class WebSocket extends EventTarget {
6060
/** @type {Handler} */
6161
#handler = {
6262
onConnectionEstablished: (response, extensions) => this.#onConnectionEstablished(response, extensions),
63-
onFail: (code, reason) => this.#onFail(code, reason),
63+
onFail: (code, reason, cause) => this.#onFail(code, reason, cause),
6464
onMessage: (opcode, data) => this.#onMessage(opcode, data),
6565
onParserError: (err) => failWebsocketConnection(this.#handler, null, err.message),
6666
onParserDrain: () => this.#onParserDrain(),
@@ -462,11 +462,11 @@ class WebSocket extends EventTarget {
462462
fireEvent('open', this)
463463
}
464464

465-
#onFail (code, reason) {
465+
#onFail (code, reason, cause) {
466466
if (reason) {
467467
// TODO: process.nextTick
468468
fireEvent('error', this, (type, init) => new ErrorEvent(type, init), {
469-
error: new Error(reason),
469+
error: new Error(reason, cause ? { cause } : undefined),
470470
message: reason
471471
})
472472
}

test/types/websocket.test-d.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import { ReadableStream, WritableStream } from 'stream/web'
22
import { expectType } from 'tsd'
3-
import { WebSocketStream } from '../../types'
3+
import { WebSocketStream, ErrorEvent } from '../../types'
44

55
declare const webSocketStream: WebSocketStream
66
const webSocketStreamOpened = await webSocketStream.opened
77

8+
declare const errorEvent: ErrorEvent
9+
810
// Test that the readable and writable streams are of identical types to ones from stream/web
911
expectType<WritableStream>(webSocketStreamOpened.writable)
1012
expectType<ReadableStream>(webSocketStreamOpened.readable)
13+
14+
expectType<Error>(errorEvent.error)

test/websocket/issue-4273.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
'use strict'
2+
3+
const { test } = require('node:test')
4+
const { WebSocket } = require('../..')
5+
const { tspl } = require('@matteo.collina/tspl')
6+
7+
test('first error than close event is fired on failed connection', async (t) => {
8+
const { completed, ok } = tspl(t, { plan: 1 })
9+
const ws = new WebSocket('ws://localhost:1')
10+
11+
ws.addEventListener('error', (ev) => {
12+
const { cause } = ev.error
13+
ok(cause instanceof Error)
14+
})
15+
16+
await completed
17+
})

types/websocket.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ interface ErrorEvent extends Event {
136136
readonly filename: string
137137
readonly lineno: number
138138
readonly colno: number
139-
readonly error: any
139+
readonly error: Error
140140
}
141141

142142
export declare const ErrorEvent: {

0 commit comments

Comments
 (0)