Skip to content

Commit 6f0ec79

Browse files
committed
http,stream: make virtual methods throw an error
Make virtual methods throw an ERR_METHOD_NOT_IMPLEMENTED error instead of emitting it. The error is not recoverable and the only way to handle it is to override the method. PR-URL: #31912 Refs: #31818 (review) Reviewed-By: Robert Nagy <ronagy@icloud.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 86ab4ee commit 6f0ec79

10 files changed

+63
-46
lines changed

lib/_http_outgoing.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,7 @@ OutgoingMessage.prototype.removeHeader = function removeHeader(name) {
619619

620620

621621
OutgoingMessage.prototype._implicitHeader = function _implicitHeader() {
622-
this.emit('error', new ERR_METHOD_NOT_IMPLEMENTED('_implicitHeader()'));
622+
throw new ERR_METHOD_NOT_IMPLEMENTED('_implicitHeader()');
623623
};
624624

625625
ObjectDefineProperty(OutgoingMessage.prototype, 'headersSent', {

lib/_stream_readable.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,7 @@ function maybeReadMore_(stream, state) {
628628
// for virtual (non-string, non-buffer) streams, "length" is somewhat
629629
// arbitrary, and perhaps not very meaningful.
630630
Readable.prototype._read = function(n) {
631-
errorOrDestroy(this, new ERR_METHOD_NOT_IMPLEMENTED('_read()'));
631+
throw new ERR_METHOD_NOT_IMPLEMENTED('_read()');
632632
};
633633

634634
Readable.prototype.pipe = function(dest, pipeOpts) {

lib/_stream_transform.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ Transform.prototype.push = function(chunk, encoding) {
163163
// an error, then that'll put the hurt on the whole operation. If you
164164
// never call cb(), then you'll never get another chunk.
165165
Transform.prototype._transform = function(chunk, encoding, cb) {
166-
cb(new ERR_METHOD_NOT_IMPLEMENTED('_transform()'));
166+
throw new ERR_METHOD_NOT_IMPLEMENTED('_transform()');
167167
};
168168

169169
Transform.prototype._write = function(chunk, encoding, cb) {

lib/_stream_writable.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,7 @@ Writable.prototype._write = function(chunk, encoding, cb) {
562562
if (this._writev) {
563563
this._writev([{ chunk, encoding }], cb);
564564
} else {
565-
process.nextTick(cb, new ERR_METHOD_NOT_IMPLEMENTED('_write()'));
565+
throw new ERR_METHOD_NOT_IMPLEMENTED('_write()');
566566
}
567567
};
568568

test/parallel/test-http-outgoing-proto.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
'use strict';
2-
const common = require('../common');
2+
require('../common');
33
const assert = require('assert');
44

55
const http = require('http');
@@ -62,13 +62,16 @@ assert.throws(() => {
6262
{
6363
const outgoingMessage = new OutgoingMessage();
6464

65-
outgoingMessage.on('error', common.expectsError({
66-
code: 'ERR_METHOD_NOT_IMPLEMENTED',
67-
name: 'Error',
68-
message: 'The _implicitHeader() method is not implemented'
69-
}));
70-
71-
outgoingMessage.write('');
65+
assert.throws(
66+
() => {
67+
outgoingMessage.write('');
68+
},
69+
{
70+
code: 'ERR_METHOD_NOT_IMPLEMENTED',
71+
name: 'Error',
72+
message: 'The _implicitHeader() method is not implemented'
73+
}
74+
);
7275
}
7376

7477
assert(OutgoingMessage.prototype.write.call({ _header: 'test' }));

test/parallel/test-stream-readable-async-iterators.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ async function tests() {
1414
{
1515
const AsyncIteratorPrototype = Object.getPrototypeOf(
1616
Object.getPrototypeOf(async function* () {}).prototype);
17-
const rs = new Readable({});
17+
const rs = new Readable({
18+
read() {}
19+
});
1820
assert.strictEqual(
1921
Object.getPrototypeOf(Object.getPrototypeOf(rs[Symbol.asyncIterator]())),
2022
AsyncIteratorPrototype);
Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
'use strict';
2-
const common = require('../common');
2+
require('../common');
33

4+
const assert = require('assert');
45
const { Readable } = require('stream');
56

67
const readable = new Readable();
78

8-
readable.on('error', common.expectsError({
9-
code: 'ERR_METHOD_NOT_IMPLEMENTED',
10-
name: 'Error',
11-
message: 'The _read() method is not implemented'
12-
}));
13-
14-
readable.read();
9+
assert.throws(
10+
() => {
11+
readable.read();
12+
},
13+
{
14+
code: 'ERR_METHOD_NOT_IMPLEMENTED',
15+
name: 'Error',
16+
message: 'The _read() method is not implemented'
17+
}
18+
);

test/parallel/test-stream-transform-constructor-set-methods.js

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
'use strict';
22
const common = require('../common');
33

4-
const { strictEqual } = require('assert');
4+
const assert = require('assert');
55
const { Transform } = require('stream');
66

77
const t = new Transform();
88

9-
t.on('error', common.expectsError({
10-
name: 'Error',
11-
code: 'ERR_METHOD_NOT_IMPLEMENTED',
12-
message: 'The _transform() method is not implemented'
13-
}));
14-
15-
t.end(Buffer.from('blerg'));
9+
assert.throws(
10+
() => {
11+
t.end(Buffer.from('blerg'));
12+
},
13+
{
14+
name: 'Error',
15+
code: 'ERR_METHOD_NOT_IMPLEMENTED',
16+
message: 'The _transform() method is not implemented'
17+
}
18+
);
1619

1720
const _transform = common.mustCall((chunk, _, next) => {
1821
next();
@@ -32,9 +35,9 @@ const t2 = new Transform({
3235
final: _final
3336
});
3437

35-
strictEqual(t2._transform, _transform);
36-
strictEqual(t2._flush, _flush);
37-
strictEqual(t2._final, _final);
38+
assert.strictEqual(t2._transform, _transform);
39+
assert.strictEqual(t2._flush, _flush);
40+
assert.strictEqual(t2._final, _final);
3841

3942
t2.end(Buffer.from('blerg'));
4043
t2.resume();

test/parallel/test-stream-writable-constructor-set-methods.js

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,36 @@
11
'use strict';
22
const common = require('../common');
33

4-
const { strictEqual } = require('assert');
4+
const assert = require('assert');
55
const { Writable } = require('stream');
66

7-
const w = new Writable();
8-
9-
w.on('error', common.expectsError({
10-
name: 'Error',
11-
code: 'ERR_METHOD_NOT_IMPLEMENTED',
12-
message: 'The _write() method is not implemented'
13-
}));
14-
157
const bufferBlerg = Buffer.from('blerg');
8+
const w = new Writable();
169

17-
w.end(bufferBlerg);
10+
assert.throws(
11+
() => {
12+
w.end(bufferBlerg);
13+
},
14+
{
15+
name: 'Error',
16+
code: 'ERR_METHOD_NOT_IMPLEMENTED',
17+
message: 'The _write() method is not implemented'
18+
}
19+
);
1820

1921
const _write = common.mustCall((chunk, _, next) => {
2022
next();
2123
});
2224

2325
const _writev = common.mustCall((chunks, next) => {
24-
strictEqual(chunks.length, 2);
26+
assert.strictEqual(chunks.length, 2);
2527
next();
2628
});
2729

2830
const w2 = new Writable({ write: _write, writev: _writev });
2931

30-
strictEqual(w2._write, _write);
31-
strictEqual(w2._writev, _writev);
32+
assert.strictEqual(w2._write, _write);
33+
assert.strictEqual(w2._writev, _writev);
3234

3335
w2.write(bufferBlerg);
3436

test/parallel/test-tls-socket-allow-half-open-option.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ const tls = require('tls');
2121
{
2222
// The option is ignored when the `socket` argument is a generic
2323
// `stream.Duplex`.
24-
const duplex = new stream.Duplex({ allowHalfOpen: false });
24+
const duplex = new stream.Duplex({
25+
allowHalfOpen: false,
26+
read() {}
27+
});
2528
const socket = new tls.TLSSocket(duplex, { allowHalfOpen: true });
2629
assert.strictEqual(socket.allowHalfOpen, false);
2730
}

0 commit comments

Comments
 (0)