@@ -183,7 +183,35 @@ const domainSet = new SafeWeakSet(); |
183 | 183 | const kBufferedCommandSymbol = Symbol('bufferedCommand'); |
184 | 184 | const kLoadingSymbol = Symbol('loading'); |
185 | 185 |
|
186 | | -let addedNewListener = false; |
| 186 | +function processNewListener(event, listener) { |
| 187 | + if (event === 'uncaughtException' && |
| 188 | + process.domain && |
| 189 | + listener.name !== 'domainUncaughtExceptionClear' && |
| 190 | + domainSet.has(process.domain)) { |
| 191 | + // Throw an error so that the event will not be added and the current |
| 192 | + // domain takes over. That way the user is notified about the error |
| 193 | + // and the current code evaluation is stopped, just as any other code |
| 194 | + // that contains an error. |
| 195 | + throw new ERR_INVALID_REPL_INPUT( |
| 196 | + 'Listeners for `uncaughtException` cannot be used in the REPL'); |
| 197 | + } |
| 198 | +} |
| 199 | + |
| 200 | +let processNewListenerUseCount = 0; |
| 201 | +function addProcessNewListener() { |
| 202 | + if (processNewListenerUseCount++ === 0) { |
| 203 | + // Add this listener only once and use a WeakSet that contains the REPLs |
| 204 | + // domains. Otherwise we'd have to add a single listener to each REPL |
| 205 | + // instance and that could trigger the `MaxListenersExceededWarning`. |
| 206 | + process.prependListener('newListener', processNewListener); |
| 207 | + } |
| 208 | +} |
| 209 | + |
| 210 | +function removeProcessNewListener() { |
| 211 | + if (--processNewListenerUseCount === 0) { |
| 212 | + process.removeListener('newListener', processNewListener); |
| 213 | + } |
| 214 | +} |
187 | 215 |
|
188 | 216 | fixReplRequire(module); |
189 | 217 |
|
@@ -337,24 +365,9 @@ class REPLServer extends Interface { |
337 | 365 | // It is possible to introspect the running REPL accessing this variable |
338 | 366 | // from inside the REPL. This is useful for anyone working on the REPL. |
339 | 367 | module.exports.repl = this; |
340 | | - } else if (!addedNewListener) { |
341 | | - // Add this listener only once and use a WeakSet that contains the REPLs |
342 | | - // domains. Otherwise we'd have to add a single listener to each REPL |
343 | | - // instance and that could trigger the `MaxListenersExceededWarning`. |
344 | | - process.prependListener('newListener', (event, listener) => { |
345 | | - if (event === 'uncaughtException' && |
346 | | - process.domain && |
347 | | - listener.name !== 'domainUncaughtExceptionClear' && |
348 | | - domainSet.has(process.domain)) { |
349 | | - // Throw an error so that the event will not be added and the current |
350 | | - // domain takes over. That way the user is notified about the error |
351 | | - // and the current code evaluation is stopped, just as any other code |
352 | | - // that contains an error. |
353 | | - throw new ERR_INVALID_REPL_INPUT( |
354 | | - 'Listeners for `uncaughtException` cannot be used in the REPL'); |
355 | | - } |
356 | | - }); |
357 | | - addedNewListener = true; |
| 368 | + } else { |
| 369 | + addProcessNewListener(); |
| 370 | + this.once('exit', removeProcessNewListener); |
358 | 371 | } |
359 | 372 |
|
360 | 373 | domainSet.add(this._domain); |
|