Skip to content

Commit 3e7f69c

Browse files
authored
[fix] Do not swallow errors emitted while destroying (#1672)
Refs: nodejs/node#29197
1 parent a39756a commit 3e7f69c

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

lib/stream.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ function createWebSocketStream(ws, options) {
7878
});
7979

8080
ws.once('error', function error(err) {
81+
if (duplex.destroyed) return;
82+
8183
duplex.destroy(err);
8284
});
8385

@@ -94,8 +96,15 @@ function createWebSocketStream(ws, options) {
9496
return;
9597
}
9698

97-
ws.once('close', function close() {
99+
let called = false;
100+
101+
ws.once('error', function error(err) {
102+
called = true;
98103
callback(err);
104+
});
105+
106+
ws.once('close', function close() {
107+
if (!called) callback(err);
99108
process.nextTick(emitClose, duplex);
100109
});
101110
ws.terminate();

test/create-websocket-stream.test.js

+46
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,52 @@ describe('createWebSocketStream', () => {
225225
});
226226
});
227227

228+
it('does not swallow errors that may occur while destroying', (done) => {
229+
const frame = Buffer.concat(
230+
Sender.frame(Buffer.from([0x22, 0xfa, 0xec, 0x78]), {
231+
fin: true,
232+
rsv1: true,
233+
opcode: 0x02,
234+
mask: false,
235+
readOnly: false
236+
})
237+
);
238+
239+
const wss = new WebSocket.Server(
240+
{
241+
perMessageDeflate: true,
242+
port: 0
243+
},
244+
() => {
245+
const ws = new WebSocket(`ws://localhost:${wss.address().port}`);
246+
const duplex = createWebSocketStream(ws);
247+
248+
duplex.on('error', (err) => {
249+
assert.ok(err instanceof Error);
250+
assert.strictEqual(err.code, 'Z_DATA_ERROR');
251+
assert.strictEqual(err.errno, -3);
252+
253+
duplex.on('close', () => {
254+
wss.close(done);
255+
});
256+
});
257+
258+
let bytesRead = 0;
259+
260+
ws.on('open', () => {
261+
ws._socket.on('data', (chunk) => {
262+
bytesRead += chunk.length;
263+
if (bytesRead === frame.length) duplex.destroy();
264+
});
265+
});
266+
}
267+
);
268+
269+
wss.on('connection', (ws) => {
270+
ws._socket.write(frame);
271+
});
272+
});
273+
228274
it("does not suppress the throwing behavior of 'error' events", (done) => {
229275
const wss = new WebSocket.Server({ port: 0 }, () => {
230276
const ws = new WebSocket(`ws://localhost:${wss.address().port}`);

test/permessage-deflate.test.js

+1
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@ describe('PerMessageDeflate', () => {
589589
perMessageDeflate.accept([{}]);
590590
perMessageDeflate.decompress(data, true, (err) => {
591591
assert.ok(err instanceof Error);
592+
assert.strictEqual(err.code, 'Z_DATA_ERROR');
592593
assert.strictEqual(err.errno, -3);
593594
done();
594595
});

0 commit comments

Comments
 (0)