1
1
'use strict' ;
2
2
3
+ function needError ( stream , err ) {
4
+ if ( ! err ) {
5
+ return false ;
6
+ }
7
+
8
+ const r = stream . _readableState ;
9
+ const w = stream . _writableState ;
10
+
11
+ if ( ( w && w . errorEmitted ) || ( r && r . errorEmitted ) ) {
12
+ return false ;
13
+ }
14
+
15
+ if ( w ) {
16
+ w . errorEmitted = true ;
17
+ }
18
+ if ( r ) {
19
+ r . errorEmitted = true ;
20
+ }
21
+
22
+ return true ;
23
+ }
24
+
3
25
// Undocumented cb() API, needed for core, not for public API
4
26
function destroy ( err , cb ) {
5
- const readableDestroyed = this . _readableState &&
6
- this . _readableState . destroyed ;
7
- const writableDestroyed = this . _writableState &&
8
- this . _writableState . destroyed ;
27
+ const r = this . _readableState ;
28
+ const w = this . _writableState ;
9
29
10
- if ( readableDestroyed || writableDestroyed ) {
30
+ if ( ( w && w . destroyed ) || ( r && r . destroyed ) ) {
11
31
if ( cb ) {
12
32
cb ( err ) ;
13
- } else if ( err ) {
14
- if ( ! this . _writableState ) {
15
- process . nextTick ( emitErrorNT , this , err ) ;
16
- } else if ( ! this . _writableState . errorEmitted ) {
17
- this . _writableState . errorEmitted = true ;
18
- process . nextTick ( emitErrorNT , this , err ) ;
19
- }
33
+ } else if ( needError ( this , err ) ) {
34
+ process . nextTick ( emitErrorNT , this , err ) ;
20
35
}
21
36
22
37
return this ;
@@ -25,28 +40,19 @@ function destroy(err, cb) {
25
40
// We set destroyed to true before firing error callbacks in order
26
41
// to make it re-entrance safe in case destroy() is called within callbacks
27
42
28
- if ( this . _readableState ) {
29
- this . _readableState . destroyed = true ;
43
+ if ( w ) {
44
+ w . destroyed = true ;
30
45
}
31
-
32
- // If this is a duplex stream mark the writable part as destroyed as well
33
- if ( this . _writableState ) {
34
- this . _writableState . destroyed = true ;
46
+ if ( r ) {
47
+ r . destroyed = true ;
35
48
}
36
49
37
50
this . _destroy ( err || null , ( err ) => {
38
- if ( ! cb && err ) {
39
- if ( ! this . _writableState ) {
40
- process . nextTick ( emitErrorAndCloseNT , this , err ) ;
41
- } else if ( ! this . _writableState . errorEmitted ) {
42
- this . _writableState . errorEmitted = true ;
43
- process . nextTick ( emitErrorAndCloseNT , this , err ) ;
44
- } else {
45
- process . nextTick ( emitCloseNT , this ) ;
46
- }
47
- } else if ( cb ) {
51
+ if ( cb ) {
48
52
process . nextTick ( emitCloseNT , this ) ;
49
53
cb ( err ) ;
54
+ } else if ( needError ( this , err ) ) {
55
+ process . nextTick ( emitErrorAndCloseNT , this , err ) ;
50
56
} else {
51
57
process . nextTick ( emitCloseNT , this ) ;
52
58
}
@@ -61,29 +67,36 @@ function emitErrorAndCloseNT(self, err) {
61
67
}
62
68
63
69
function emitCloseNT ( self ) {
64
- if ( self . _writableState && ! self . _writableState . emitClose )
70
+ const r = self . _readableState ;
71
+ const w = self . _writableState ;
72
+
73
+ if ( w && ! w . emitClose )
65
74
return ;
66
- if ( self . _readableState && ! self . _readableState . emitClose )
75
+ if ( r && ! r . emitClose )
67
76
return ;
68
77
self . emit ( 'close' ) ;
69
78
}
70
79
71
80
function undestroy ( ) {
72
- if ( this . _readableState ) {
73
- this . _readableState . destroyed = false ;
74
- this . _readableState . reading = false ;
75
- this . _readableState . ended = false ;
76
- this . _readableState . endEmitted = false ;
81
+ const r = this . _readableState ;
82
+ const w = this . _writableState ;
83
+
84
+ if ( r ) {
85
+ r . destroyed = false ;
86
+ r . reading = false ;
87
+ r . ended = false ;
88
+ r . endEmitted = false ;
89
+ r . errorEmitted = false ;
77
90
}
78
91
79
- if ( this . _writableState ) {
80
- this . _writableState . destroyed = false ;
81
- this . _writableState . ended = false ;
82
- this . _writableState . ending = false ;
83
- this . _writableState . finalCalled = false ;
84
- this . _writableState . prefinished = false ;
85
- this . _writableState . finished = false ;
86
- this . _writableState . errorEmitted = false ;
92
+ if ( w ) {
93
+ w . destroyed = false ;
94
+ w . ended = false ;
95
+ w . ending = false ;
96
+ w . finalCalled = false ;
97
+ w . prefinished = false ;
98
+ w . finished = false ;
99
+ w . errorEmitted = false ;
87
100
}
88
101
}
89
102
@@ -98,12 +111,12 @@ function errorOrDestroy(stream, err) {
98
111
// the error to be emitted nextTick. In a future
99
112
// semver major update we should change the default to this.
100
113
101
- const rState = stream . _readableState ;
102
- const wState = stream . _writableState ;
114
+ const r = stream . _readableState ;
115
+ const w = stream . _writableState ;
103
116
104
- if ( ( rState && rState . autoDestroy ) || ( wState && wState . autoDestroy ) )
117
+ if ( ( r && r . autoDestroy ) || ( w && w . autoDestroy ) )
105
118
stream . destroy ( err ) ;
106
- else
119
+ else if ( needError ( stream , err ) )
107
120
stream . emit ( 'error' , err ) ;
108
121
}
109
122
0 commit comments