Skip to content

Commit f217025

Browse files
committed
stream: add errored and closed props
PR-URL: #40696 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 3e5a5e8 commit f217025

File tree

10 files changed

+112
-15
lines changed

10 files changed

+112
-15
lines changed

‎doc/api/stream.md‎

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,16 @@ further errors except from `_destroy()` may be emitted as `'error'`.
456456
Implementors should not override this method,
457457
but instead implement [`writable._destroy()`][writable-_destroy].
458458

459+
##### `writable.closed`
460+
461+
<!-- YAML
462+
added: REPLACEME
463+
-->
464+
465+
*{boolean}
466+
467+
Is `true` after `'close'` has been emitted.
468+
459469
##### `writable.destroyed`
460470

461471
<!-- YAML
@@ -611,6 +621,17 @@ added:
611621
Number of times [`writable.uncork()`][stream-uncork] needs to be
612622
called in order to fully uncork the stream.
613623

624+
##### `writable.writableErrored`
625+
626+
<!-- YAML
627+
added:
628+
REPLACEME
629+
-->
630+
631+
*{Error}
632+
633+
Returns error if the stream has been destroyed with an error.
634+
614635
##### `writable.writableFinished`
615636

616637
<!-- YAML
@@ -1080,14 +1101,24 @@ further errors except from `_destroy()` may be emitted as `'error'`.
10801101
Implementors should not override this method, but instead implement
10811102
[`readable._destroy()`][readable-_destroy].
10821103

1083-
##### `readable.destroyed`
1104+
##### `readable.closed`
10841105

10851106
<!-- YAML
10861107
added: v8.0.0
10871108
-->
10881109

10891110
*{boolean}
10901111

1112+
Is `true` after `'close'` has been emitted.
1113+
1114+
##### `readable.destroyed`
1115+
1116+
<!-- YAML
1117+
added: REPLACEME
1118+
-->
1119+
1120+
*{boolean}
1121+
10911122
Is `true` after [`readable.destroy()`][readable-destroy] has been called.
10921123

10931124
##### `readable.isPaused()`
@@ -1346,6 +1377,17 @@ added: v12.9.0
13461377

13471378
Becomes `true` when [`'end'`][] event is emitted.
13481379

1380+
##### `readable.readableErrored`
1381+
1382+
<!-- YAML
1383+
added:
1384+
REPLACEME
1385+
-->
1386+
1387+
*{Error}
1388+
1389+
Returns error if the stream has been destroyed with an error.
1390+
13491391
##### `readable.readableFlowing`
13501392

13511393
<!-- YAML

‎lib/internal/fs/streams.js‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,9 @@ const FileHandleOperations = (handle) =>{
107107

108108
functionclose(stream,err,cb){
109109
if(!stream.fd){
110-
// TODO(ronag)
111-
// stream.closed = true;
112110
cb(err);
113111
}else{
114112
stream[kFs].close(stream.fd,(er)=>{
115-
stream.closed=true;
116113
cb(er||err);
117114
});
118115
stream.fd=null;
@@ -186,7 +183,6 @@ function ReadStream(path, options){
186183
this.end=options.end;
187184
this.pos=undefined;
188185
this.bytesRead=0;
189-
this.closed=false;
190186
this[kIsPerformingIO]=false;
191187

192188
if(this.start!==undefined){
@@ -358,10 +354,8 @@ function WriteStream(path, options){
358354
this.start=options.start;
359355
this.pos=undefined;
360356
this.bytesWritten=0;
361-
this.closed=false;
362357
this[kIsPerformingIO]=false;
363358

364-
365359
if(this.start!==undefined){
366360
validateInteger(this.start,'start',0);
367361

‎lib/internal/streams/end-of-stream.js‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ const{
2222
isReadable,
2323
isReadableNodeStream,
2424
isReadableFinished,
25+
isReadableErrored,
2526
isWritable,
2627
isWritableNodeStream,
2728
isWritableFinished,
29+
isWritableErrored,
2830
isNodeStream,
2931
willEmitClose: _willEmitClose,
3032
}=require('internal/streams/utils');
@@ -110,7 +112,7 @@ function eos(stream, options, callback){
110112
constonclose=()=>{
111113
closed=true;
112114

113-
consterrored=wState?.errored||rState?.errored;
115+
consterrored=isWritableErrored(stream)||isReadableErrored(stream);
114116

115117
if(errored&&typeoferrored!=='boolean'){
116118
returncallback.call(stream,errored);

‎lib/internal/streams/readable.js‎

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,13 +1239,23 @@ ObjectDefineProperties(Readable.prototype,{
12391239
}
12401240
},
12411241

1242+
readableErrored: {
1243+
enumerable: false,
1244+
get(){
1245+
returnthis._readableState ? this._readableState.errored : null;
1246+
}
1247+
},
1248+
1249+
closed: {
1250+
get(){
1251+
returnthis._readableState ? this._readableState.closed : false;
1252+
}
1253+
},
1254+
12421255
destroyed: {
12431256
enumerable: false,
12441257
get(){
1245-
if(this._readableState===undefined){
1246-
returnfalse;
1247-
}
1248-
returnthis._readableState.destroyed;
1258+
returnthis._readableState ? this._readableState.destroyed : false;
12491259
},
12501260
set(value){
12511261
// We ignore the value if the stream

‎lib/internal/streams/utils.js‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,39 @@ function isFinished(stream, opts){
144144
returntrue;
145145
}
146146

147+
functionisWritableErrored(stream){
148+
if(!isNodeStream(stream)){
149+
returnnull;
150+
}
151+
152+
if(stream.writableErrored){
153+
returnstream.writableErrored;
154+
}
155+
156+
returnstream._writableState?.errored??null;
157+
}
158+
159+
functionisReadableErrored(stream){
160+
if(!isNodeStream(stream)){
161+
returnnull;
162+
}
163+
164+
if(stream.readableErrored){
165+
returnstream.readableErrored;
166+
}
167+
168+
returnstream._readableState?.errored??null;
169+
}
170+
147171
functionisClosed(stream){
148172
if(!isNodeStream(stream)){
149173
returnnull;
150174
}
151175

176+
if(typeofstream.closed==='boolean'){
177+
returnstream.closed;
178+
}
179+
152180
constwState=stream._writableState;
153181
constrState=stream._readableState;
154182

@@ -226,11 +254,13 @@ module.exports ={
226254
isReadableNodeStream,
227255
isReadableEnded,
228256
isReadableFinished,
257+
isReadableErrored,
229258
isNodeStream,
230259
isWritable,
231260
isWritableNodeStream,
232261
isWritableEnded,
233262
isWritableFinished,
263+
isWritableErrored,
234264
isServerRequest,
235265
isServerResponse,
236266
willEmitClose,

‎lib/internal/streams/writable.js‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,12 @@ function finish(stream, state){
768768

769769
ObjectDefineProperties(Writable.prototype,{
770770

771+
closed: {
772+
get(){
773+
returnthis._writableState ? this._writableState.closed : false;
774+
}
775+
},
776+
771777
destroyed: {
772778
get(){
773779
returnthis._writableState ? this._writableState.destroyed : false;
@@ -846,7 +852,14 @@ ObjectDefineProperties(Writable.prototype,{
846852
get(){
847853
returnthis._writableState&&this._writableState.length;
848854
}
849-
}
855+
},
856+
857+
writableErrored: {
858+
enumerable: false,
859+
get(){
860+
returnthis._writableState ? this._writableState.errored : null;
861+
}
862+
},
850863
});
851864

852865
constdestroy=destroyImpl.destroy;

‎test/parallel/test-fs-read-stream-inherit.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ const rangeFile = fixtures.path('x.txt');
199199
file.on('error',common.mustCall());
200200

201201
process.on('exit',function(){
202-
assert(!file.closed);
202+
assert(file.closed);
203203
assert(file.destroyed);
204204
});
205205
}

‎test/parallel/test-fs-read-stream.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ if (!common.isWindows){
271271
file.on('error',common.mustCall());
272272

273273
process.on('exit',function(){
274-
assert(!file.closed);
274+
assert(file.closed);
275275
assert(file.destroyed);
276276
});
277277
}

‎test/parallel/test-stream-finished.js‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,8 +612,10 @@ testClosed((opts) => new Writable({write(){}, ...opts }));
612612
constw=newWritable();
613613
const_err=newError();
614614
w.destroy(_err);
615+
assert.strictEqual(w.writableErrored,_err);
615616
finished(w,common.mustCall((err)=>{
616617
assert.strictEqual(_err,err);
618+
assert.strictEqual(w.closed,true);
617619
finished(w,common.mustCall((err)=>{
618620
assert.strictEqual(_err,err);
619621
}));
@@ -623,7 +625,9 @@ testClosed((opts) => new Writable({write(){}, ...opts }));
623625
{
624626
constw=newWritable();
625627
w.destroy();
628+
assert.strictEqual(w.writableErrored,null);
626629
finished(w,common.mustCall((err)=>{
630+
assert.strictEqual(w.closed,true);
627631
assert.strictEqual(err.code,'ERR_STREAM_PREMATURE_CLOSE');
628632
finished(w,common.mustCall((err)=>{
629633
assert.strictEqual(err.code,'ERR_STREAM_PREMATURE_CLOSE');

‎test/parallel/test-stream-readable-destroy.js‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const assert = require('assert');
1313
read.on('close',common.mustCall());
1414

1515
read.destroy();
16+
assert.strictEqual(read.readableErrored,null);
1617
assert.strictEqual(read.destroyed,true);
1718
}
1819

@@ -31,6 +32,7 @@ const assert = require('assert');
3132
}));
3233

3334
read.destroy(expected);
35+
assert.strictEqual(read.readableErrored,expected);
3436
assert.strictEqual(read.destroyed,true);
3537
}
3638

0 commit comments

Comments
(0)