@@ -98,8 +98,7 @@ function eos(stream, options, callback) {
98
98
isWritable ( stream ) === writable
99
99
) ;
100
100
101
- let writableFinished = stream . writableFinished ||
102
- ( wState && wState . finished ) ;
101
+ let writableFinished = stream . writableFinished || wState ?. finished ;
103
102
const onfinish = ( ) => {
104
103
writableFinished = true ;
105
104
// Stream should not be destroyed here. If it is that
@@ -111,8 +110,7 @@ function eos(stream, options, callback) {
111
110
if ( ! readable || readableEnded ) callback . call ( stream ) ;
112
111
} ;
113
112
114
- let readableEnded = stream . readableEnded ||
115
- ( rState && rState . endEmitted ) ;
113
+ let readableEnded = stream . readableEnded || rState ?. endEmitted ;
116
114
const onend = ( ) => {
117
115
readableEnded = true ;
118
116
// Stream should not be destroyed here. If it is that
@@ -128,7 +126,17 @@ function eos(stream, options, callback) {
128
126
callback . call ( stream , err ) ;
129
127
} ;
130
128
129
+ let closed = wState ?. closed || rState ?. closed ;
130
+
131
131
const onclose = ( ) => {
132
+ closed = true ;
133
+
134
+ const errored = wState ?. errored || rState ?. errored ;
135
+
136
+ if ( errored && typeof errored !== 'boolean' ) {
137
+ return callback . call ( stream , errored ) ;
138
+ }
139
+
132
140
if ( readable && ! readableEnded ) {
133
141
if ( ! isReadableEnded ( stream ) )
134
142
return callback . call ( stream ,
@@ -139,6 +147,7 @@ function eos(stream, options, callback) {
139
147
return callback . call ( stream ,
140
148
new ERR_STREAM_PREMATURE_CLOSE ( ) ) ;
141
149
}
150
+
142
151
callback . call ( stream ) ;
143
152
} ;
144
153
@@ -168,29 +177,29 @@ function eos(stream, options, callback) {
168
177
if ( options . error !== false ) stream . on ( 'error' , onerror ) ;
169
178
stream . on ( 'close' , onclose ) ;
170
179
171
- // _closed is for OutgoingMessage which is not a proper Writable.
172
- const closed = ( ! wState && ! rState && stream . _closed === true ) || (
173
- ( wState && wState . closed ) ||
174
- ( rState && rState . closed ) ||
175
- ( wState && wState . errorEmitted ) ||
176
- ( rState && rState . errorEmitted ) ||
177
- ( rState && stream . req && stream . aborted ) ||
178
- (
179
- ( ! writable || ( wState && wState . finished ) ) &&
180
- ( ! readable || ( rState && rState . endEmitted ) )
181
- )
182
- ) ;
183
-
184
180
if ( closed ) {
185
- // TODO(ronag): Re-throw error if errorEmitted?
186
- // TODO(ronag): Throw premature close as if finished was called?
187
- // before being closed? i.e. if closed but not errored, ended or finished.
188
- // TODO(ronag): Throw some kind of error? Does it make sense
189
- // to call finished() on a "finished" stream?
190
- // TODO(ronag): willEmitClose?
191
- process . nextTick ( ( ) => {
192
- callback ( ) ;
193
- } ) ;
181
+ process . nextTick ( onclose ) ;
182
+ } else if ( wState ?. errorEmitted || rState ?. errorEmitted ) {
183
+ if ( ! willEmitClose ) {
184
+ process . nextTick ( onclose ) ;
185
+ }
186
+ } else if (
187
+ ! readable &&
188
+ ( ! willEmitClose || stream . readable ) &&
189
+ writableFinished
190
+ ) {
191
+ process . nextTick ( onclose ) ;
192
+ } else if (
193
+ ! writable &&
194
+ ( ! willEmitClose || stream . writable ) &&
195
+ readableEnded
196
+ ) {
197
+ process . nextTick ( onclose ) ;
198
+ } else if ( ! wState && ! rState && stream . _closed === true ) {
199
+ // _closed is for OutgoingMessage which is not a proper Writable.
200
+ process . nextTick ( onclose ) ;
201
+ } else if ( ( rState && stream . req && stream . aborted ) ) {
202
+ process . nextTick ( onclose ) ;
194
203
}
195
204
196
205
const cleanup = ( ) => {
0 commit comments