@@ -142,13 +142,21 @@ function getContextLinesFromFile(path: string, ranges: ReadlineRange[], output:
142
142
input : stream ,
143
143
} ) ;
144
144
145
+ // We need to explicitly destroy the stream to prevent memory leaks,
146
+ // removing the listeners on the readline interface is not enough.
147
+ // See: https://github.com/nodejs/node/issues/9002 and https://github.com/getsentry/sentry-javascript/issues/14892
148
+ function destroyStreamAndResolve ( ) : void {
149
+ stream . destroy ( ) ;
150
+ resolve ( ) ;
151
+ }
152
+
145
153
// Init at zero and increment at the start of the loop because lines are 1 indexed.
146
154
let lineNumber = 0 ;
147
155
let currentRangeIndex = 0 ;
148
156
const range = ranges [ currentRangeIndex ] ;
149
157
if ( range === undefined ) {
150
158
// We should never reach this point, but if we do, we should resolve the promise to prevent it from hanging.
151
- resolve ( ) ;
159
+ destroyStreamAndResolve ( ) ;
152
160
return ;
153
161
}
154
162
let rangeStart = range [ 0 ] ;
@@ -162,14 +170,14 @@ function getContextLinesFromFile(path: string, ranges: ReadlineRange[], output:
162
170
DEBUG_BUILD && logger . error ( `Failed to read file: ${ path } . Error: ${ e } ` ) ;
163
171
lineReaded . close ( ) ;
164
172
lineReaded . removeAllListeners ( ) ;
165
- resolve ( ) ;
173
+ destroyStreamAndResolve ( ) ;
166
174
}
167
175
168
176
// We need to handle the error event to prevent the process from crashing in < Node 16
169
177
// https://github.com/nodejs/node/pull/31603
170
178
stream . on ( 'error' , onStreamError ) ;
171
179
lineReaded . on ( 'error' , onStreamError ) ;
172
- lineReaded . on ( 'close' , resolve ) ;
180
+ lineReaded . on ( 'close' , destroyStreamAndResolve ) ;
173
181
174
182
lineReaded . on ( 'line' , line => {
175
183
lineNumber ++ ;
0 commit comments