| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent acac0f8 commit 5e3f516
18 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1449,6 +1449,12 @@ An unspecified or non-specific system error has occurred within the Node.js | |||
| 1449 | 1449 | process. The error object will have an `err.info` object property with | |
| 1450 | 1450 | additional details. | |
| 1451 | 1451 | ||
| 1452 | + <a id="ERR_STREAM_DESTROYED"></a> | ||
| 1453 | + ### ERR_STREAM_DESTROYED | ||
| 1454 | + | ||
| 1455 | + A stream method was called that cannot complete because the stream was | ||
| 1456 | + destroyed using `stream.destroy()`. | ||
| 1457 | + | ||
| 1452 | 1458 | <a id="ERR_TLS_CERT_ALTNAME_INVALID"></a> | |
| 1453 | 1459 | ### ERR_TLS_CERT_ALTNAME_INVALID | |
| 1454 | 1460 | ||
@@ -1615,11 +1621,6 @@ The fulfilled value of a linking promise is not a `vm.Module` object. | |||
| 1615 | 1621 | The current module's status does not allow for this operation. The specific | |
| 1616 | 1622 | meaning of the error depends on the specific function. | |
| 1617 | 1623 | ||
| 1618 | - <a id="ERR_ZLIB_BINDING_CLOSED"></a> | ||
| 1619 | - ### ERR_ZLIB_BINDING_CLOSED | ||
| 1620 | - | ||
| 1621 | - An attempt was made to use a `zlib` object after it has already been closed. | ||
| 1622 | - | ||
| 1623 | 1624 | <a id="ERR_ZLIB_INITIALIZATION_FAILED"></a> | |
| 1624 | 1625 | ### ERR_ZLIB_INITIALIZATION_FAILED | |
| 1625 | 1626 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -543,8 +543,10 @@ added: v8.0.0 | |||
| 543 | 543 | ||
| 544 | 544 | * Returns: {this} | |
| 545 | 545 | ||
| 546 | - Destroy the stream, and emit the passed error. After this call, the | ||
| 547 | - writable stream has ended. Implementors should not override this method, | ||
| 546 | + Destroy the stream, and emit the passed `error` and a `close` event. | ||
| 547 | + After this call, the writable stream has ended and subsequent calls | ||
| 548 | + to `write` / `end` will give an `ERR_STREAM_DESTROYED` error. | ||
| 549 | + Implementors should not override this method, | ||
| 548 | 550 | but instead implement [`writable._destroy`][writable-_destroy]. | |
| 549 | 551 | ||
| 550 | 552 | ### Readable Streams | |
@@ -1167,8 +1169,9 @@ myReader.on('readable', () => { | |||
| 1167 | 1169 | added: v8.0.0 | |
| 1168 | 1170 | --> | |
| 1169 | 1171 | ||
| 1170 | - Destroy the stream, and emit `'error'`. After this call, the | ||
| 1171 | - readable stream will release any internal resources. | ||
| 1172 | + Destroy the stream, and emit `'error'` and `close`. After this call, the | ||
| 1173 | + readable stream will release any internal resources and subsequent calls | ||
| 1174 | + to `push` will be ignored. | ||
| 1172 | 1175 | Implementors should not override this method, but instead implement | |
| 1173 | 1176 | [`readable._destroy`][readable-_destroy]. | |
| 1174 | 1177 | ||
@@ -1382,6 +1385,12 @@ constructor and implement the `writable._write()` method. The | |||
| 1382 | 1385 | `writable._writev()` method *may* also be implemented. | |
| 1383 | 1386 | ||
| 1384 | 1387 | #### Constructor: new stream.Writable([options]) | |
| 1388 | + <!-- YAML | ||
| 1389 | + changes: | ||
| 1390 | + - version: REPLACEME | ||
| 1391 | + pr-url: https://github.com/nodejs/node/pull/18438 | ||
| 1392 | + description: Add `emitClose` option to specify if `close` is emitted on destroy | ||
| 1393 | + --> | ||
| 1385 | 1394 | ||
| 1386 | 1395 | * `options` {Object} | |
| 1387 | 1396 | * `highWaterMark` {number} Buffer level when | |
@@ -1395,6 +1404,8 @@ constructor and implement the `writable._write()` method. The | |||
| 1395 | 1404 | it becomes possible to write JavaScript values other than string, | |
| 1396 | 1405 | `Buffer` or `Uint8Array` if supported by the stream implementation. | |
| 1397 | 1406 | Defaults to `false` | |
| 1407 | + * `emitClose` {boolean} Whether or not the stream should emit `close` | ||
| 1408 | + after it has been destroyed. Defaults to `true` | ||
| 1398 | 1409 | * `write` {Function} Implementation for the | |
| 1399 | 1410 | [`stream._write()`][stream-_write] method. | |
| 1400 | 1411 | * `writev` {Function} Implementation for the | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -135,10 +135,3 @@ Object.defineProperty(Duplex.prototype, 'destroyed', { | |||
| 135 | 135 | this._writableState.destroyed = value; | |
| 136 | 136 | } | |
| 137 | 137 | }); | |
| 138 | - | ||
| 139 | - Duplex.prototype._destroy = function(err, cb) { | ||
| 140 | - this.push(null); | ||
| 141 | - this.end(); | ||
| 142 | - | ||
| 143 | - process.nextTick(cb, err); | ||
| 144 | - }; | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -106,6 +106,9 @@ function ReadableState(options, stream) { | |||
| 106 | 106 | this.readableListening = false; | |
| 107 | 107 | this.resumeScheduled = false; | |
| 108 | 108 | ||
| 109 | + // Should close be emitted on destroy. Defaults to true. | ||
| 110 | + this.emitClose = options.emitClose !== false; | ||
| 111 | + | ||
| 109 | 112 | // has it been destroyed | |
| 110 | 113 | this.destroyed = false; | |
| 111 | 114 | ||
@@ -177,7 +180,6 @@ Object.defineProperty(Readable.prototype, 'destroyed', { | |||
| 177 | 180 | Readable.prototype.destroy = destroyImpl.destroy; | |
| 178 | 181 | Readable.prototype._undestroy = destroyImpl.undestroy; | |
| 179 | 182 | Readable.prototype._destroy = function(err, cb) { | |
| 180 | - this.push(null); | ||
| 181 | 183 | cb(err); | |
| 182 | 184 | }; | |
| 183 | 185 | ||
@@ -236,6 +238,8 @@ function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) { | |||
| 236 | 238 | addChunk(stream, state, chunk, true); | |
| 237 | 239 | } else if (state.ended) { | |
| 238 | 240 | stream.emit('error', new errors.Error('ERR_STREAM_PUSH_AFTER_EOF')); | |
| 241 | + } else if (state.destroyed) { | ||
| 242 | + return false; | ||
| 239 | 243 | } else { | |
| 240 | 244 | state.reading = false; | |
| 241 | 245 | if (state.decoder && !encoding) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -132,7 +132,7 @@ function Transform(options) { | |||
| 132 | 132 | } | |
| 133 | 133 | ||
| 134 | 134 | function prefinish() { | |
| 135 | - if (typeof this._flush === 'function') { | ||
| 135 | + if (typeof this._flush === 'function' && !this._readableState.destroyed) { | ||
| 136 | 136 | this._flush((er, data) => { | |
| 137 | 137 | done(this, er, data); | |
| 138 | 138 | }); | |
@@ -194,7 +194,6 @@ Transform.prototype._read = function(n) { | |||
| 194 | 194 | Transform.prototype._destroy = function(err, cb) { | |
| 195 | 195 | Duplex.prototype._destroy.call(this, err, (err2) => { | |
| 196 | 196 | cb(err2); | |
| 197 | - this.emit('close'); | ||
| 198 | 197 | }); | |
| 199 | 198 | }; | |
| 200 | 199 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -134,6 +134,9 @@ function WritableState(options, stream) { | |||
| 134 | 134 | // True if the error was already emitted and should not be thrown again | |
| 135 | 135 | this.errorEmitted = false; | |
| 136 | 136 | ||
| 137 | + // Should close be emitted on destroy. Defaults to true. | ||
| 138 | + this.emitClose = options.emitClose !== false; | ||
| 139 | + | ||
| 137 | 140 | // count buffered requests | |
| 138 | 141 | this.bufferedRequestCount = 0; | |
| 139 | 142 | ||
@@ -390,7 +393,9 @@ function doWrite(stream, state, writev, len, chunk, encoding, cb) { | |||
| 390 | 393 | state.writecb = cb; | |
| 391 | 394 | state.writing = true; | |
| 392 | 395 | state.sync = true; | |
| 393 | - if (writev) | ||
| 396 | + if (state.destroyed) | ||
| 397 | + state.onwrite(new errors.Error('ERR_STREAM_DESTROYED', 'write')); | ||
| 398 | + else if (writev) | ||
| 394 | 399 | stream._writev(chunk, state.onwrite); | |
| 395 | 400 | else | |
| 396 | 401 | stream._write(chunk, encoding, state.onwrite); | |
@@ -604,7 +609,7 @@ function callFinal(stream, state) { | |||
| 604 | 609 | } | |
| 605 | 610 | function prefinish(stream, state) { | |
| 606 | 611 | if (!state.prefinished && !state.finalCalled) { | |
| 607 | - if (typeof stream._final === 'function') { | ||
| 612 | + if (typeof stream._final === 'function' && !state.destroyed) { | ||
| 608 | 613 | state.pendingcb++; | |
| 609 | 614 | state.finalCalled = true; | |
| 610 | 615 | process.nextTick(callFinal, stream, state); | |
@@ -681,6 +686,5 @@ Object.defineProperty(Writable.prototype, 'destroyed', { | |||
| 681 | 686 | Writable.prototype.destroy = destroyImpl.destroy; | |
| 682 | 687 | Writable.prototype._undestroy = destroyImpl.undestroy; | |
| 683 | 688 | Writable.prototype._destroy = function(err, cb) { | |
| 684 | - this.end(); | ||
| 685 | 689 | cb(err); | |
| 686 | 690 | }; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1929,6 +1929,9 @@ function ReadStream(path, options) { | |||
| 1929 | 1929 | if (options.highWaterMark === undefined) | |
| 1930 | 1930 | options.highWaterMark = 64 * 1024; | |
| 1931 | 1931 | ||
| 1932 | + // for backwards compat do not emit close on destroy. | ||
| 1933 | + options.emitClose = false; | ||
| 1934 | + | ||
| 1932 | 1935 | Readable.call(this, options); | |
| 1933 | 1936 | ||
| 1934 | 1937 | // path will be ignored when fd is specified, so it can be falsy | |
@@ -2084,6 +2087,9 @@ function WriteStream(path, options) { | |||
| 2084 | 2087 | ||
| 2085 | 2088 | options = copyObject(getOptions(options, {})); | |
| 2086 | 2089 | ||
| 2090 | + // for backwards compat do not emit close on destroy. | ||
| 2091 | + options.emitClose = false; | ||
| 2092 | + | ||
| 2087 | 2093 | Writable.call(this, options); | |
| 2088 | 2094 | ||
| 2089 | 2095 | // path will be ignored when fd is specified, so it can be falsy | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -843,6 +843,7 @@ E('ERR_SOCKET_DGRAM_NOT_RUNNING', 'Not running', Error); | |||
| 843 | 843 | E('ERR_STDERR_CLOSE', 'process.stderr cannot be closed', Error); | |
| 844 | 844 | E('ERR_STDOUT_CLOSE', 'process.stdout cannot be closed', Error); | |
| 845 | 845 | E('ERR_STREAM_CANNOT_PIPE', 'Cannot pipe, not readable', Error); | |
| 846 | + E('ERR_STREAM_DESTROYED', 'Cannot call %s after a stream was destroyed'); | ||
| 846 | 847 | E('ERR_STREAM_NULL_VALUES', 'May not write null values to stream', TypeError); | |
| 847 | 848 | E('ERR_STREAM_PUSH_AFTER_EOF', 'stream.push() after EOF', Error); | |
| 848 | 849 | E('ERR_STREAM_READ_NOT_IMPLEMENTED', '_read() is not implemented', Error); | |
@@ -908,7 +909,6 @@ E('ERR_VM_MODULE_NOT_LINKED', | |||
| 908 | 909 | E('ERR_VM_MODULE_NOT_MODULE', | |
| 909 | 910 | 'Provided module is not an instance of Module', Error); | |
| 910 | 911 | E('ERR_VM_MODULE_STATUS', 'Module status %s', Error); | |
| 911 | - E('ERR_ZLIB_BINDING_CLOSED', 'zlib binding closed', Error); | ||
| 912 | 912 | E('ERR_ZLIB_INITIALIZATION_FAILED', 'Initialization failed', Error); | |
| 913 | 913 | ||
| 914 | 914 | function sysError(code, syscall, path, dest, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1475,6 +1475,7 @@ class Http2Stream extends Duplex { | |||
| 1475 | 1475 | constructor(session, options) { | |
| 1476 | 1476 | options.allowHalfOpen = true; | |
| 1477 | 1477 | options.decodeStrings = false; | |
| 1478 | + options.emitClose = false; | ||
| 1478 | 1479 | super(options); | |
| 1479 | 1480 | this[async_id_symbol] = -1; | |
| 1480 | 1481 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -30,6 +30,7 @@ function destroy(err, cb) { | |||
| 30 | 30 | } | |
| 31 | 31 | ||
| 32 | 32 | this._destroy(err || null, (err) => { | |
| 33 | + process.nextTick(emitCloseNT, this); | ||
| 33 | 34 | if (!cb && err) { | |
| 34 | 35 | process.nextTick(emitErrorNT, this, err); | |
| 35 | 36 | if (this._writableState) { | |
@@ -43,6 +44,14 @@ function destroy(err, cb) { | |||
| 43 | 44 | return this; | |
| 44 | 45 | } | |
| 45 | 46 | ||
| 47 | + function emitCloseNT(self) { | ||
| 48 | + if (self._writableState && !self._writableState.emitClose) | ||
| 49 | + return; | ||
| 50 | + if (self._readableState && !self._readableState.emitClose) | ||
| 51 | + return; | ||
| 52 | + self.emit('close'); | ||
| 53 | + } | ||
| 54 | + | ||
| 46 | 55 | function undestroy() { | |
| 47 | 56 | if (this._readableState) { | |
| 48 | 57 | this._readableState.destroyed = false; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments