@@ -72,6 +72,7 @@ const {
72
72
ERR_CANNOT_WATCH_SIGINT ,
73
73
ERR_INVALID_ARG_TYPE ,
74
74
ERR_INVALID_REPL_EVAL_CONFIG ,
75
+ ERR_INVALID_REPL_INPUT ,
75
76
ERR_SCRIPT_EXECUTION_INTERRUPTED
76
77
} = require ( 'internal/errors' ) . codes ;
77
78
const { sendInspectorCommand } = require ( 'internal/util/inspector' ) ;
@@ -102,6 +103,20 @@ const replMap = new WeakMap();
102
103
const kBufferedCommandSymbol = Symbol ( 'bufferedCommand' ) ;
103
104
const kContextId = Symbol ( 'contextId' ) ;
104
105
106
+ let tmpListeners = [ ] ;
107
+ let checkUncaught = false ;
108
+ let currentListeners = [ ] ;
109
+
110
+ process . on ( 'newListener' , ( event , listener ) => {
111
+ if ( event === 'uncaughtException' &&
112
+ checkUncaught &&
113
+ ! currentListeners . includes ( listener ) ) {
114
+ // Add listener to a temporary list of listeners which should be removed
115
+ // again.
116
+ tmpListeners . push ( listener ) ;
117
+ }
118
+ } ) ;
119
+
105
120
try {
106
121
// Hack for require.resolve("./relative") to work properly.
107
122
module . filename = path . resolve ( 'repl' ) ;
@@ -268,7 +283,7 @@ function REPLServer(prompt,
268
283
// statement rather than an object literal. So, we first try
269
284
// to wrap it in parentheses, so that it will be interpreted as
270
285
// an expression. Note that if the above condition changes,
271
- // lib/internal/repl/recoverable .js needs to be changed to match.
286
+ // lib/internal/repl/utils .js needs to be changed to match.
272
287
code = `(${ code . trim ( ) } )\n` ;
273
288
wrappedCmd = true ;
274
289
}
@@ -428,7 +443,6 @@ function REPLServer(prompt,
428
443
}
429
444
430
445
self . eval = self . _domain . bind ( eval_ ) ;
431
-
432
446
self . _domain . on ( 'error' , function debugDomainError ( e ) {
433
447
debug ( 'domain error' ) ;
434
448
let errStack = '' ;
@@ -465,22 +479,31 @@ function REPLServer(prompt,
465
479
}
466
480
}
467
481
468
- if ( errStack === '' ) {
469
- errStack = `Thrown: ${ self . writer ( e ) } \n` ;
470
- } else {
471
- const ln = errStack . endsWith ( '\n' ) ? '' : '\n' ;
472
- errStack = `Thrown:\n${ errStack } ${ ln } ` ;
473
- }
474
-
475
482
if ( ! self . underscoreErrAssigned ) {
476
483
self . lastError = e ;
477
484
}
478
485
479
486
const top = replMap . get ( self ) ;
480
- top . outputStream . write ( errStack ) ;
481
- top . clearBufferedCommand ( ) ;
482
- top . lines . level = [ ] ;
483
- top . displayPrompt ( ) ;
487
+ if ( options [ kStandaloneREPL ] &&
488
+ process . listenerCount ( 'uncaughtException' ) !== 0 ) {
489
+ process . nextTick ( ( ) => {
490
+ process . emit ( 'uncaughtException' , e ) ;
491
+ top . clearBufferedCommand ( ) ;
492
+ top . lines . level = [ ] ;
493
+ top . displayPrompt ( ) ;
494
+ } ) ;
495
+ } else {
496
+ if ( errStack === '' ) {
497
+ errStack = `Thrown: ${ self . writer ( e ) } \n` ;
498
+ } else {
499
+ const ln = errStack . endsWith ( '\n' ) ? '' : '\n' ;
500
+ errStack = `Thrown:\n${ errStack } ${ ln } ` ;
501
+ }
502
+ top . outputStream . write ( errStack ) ;
503
+ top . clearBufferedCommand ( ) ;
504
+ top . lines . level = [ ] ;
505
+ top . displayPrompt ( ) ;
506
+ }
484
507
} ) ;
485
508
486
509
self . resetContext ( ) ;
@@ -666,10 +689,32 @@ function REPLServer(prompt,
666
689
const evalCmd = self [ kBufferedCommandSymbol ] + cmd + '\n' ;
667
690
668
691
debug ( 'eval %j' , evalCmd ) ;
692
+ if ( ! options [ kStandaloneREPL ] ) {
693
+ checkUncaught = true ;
694
+ currentListeners = process . listeners ( 'uncaughtException' ) ;
695
+ }
669
696
self . eval ( evalCmd , self . context , 'repl' , finish ) ;
670
697
671
698
function finish ( e , ret ) {
672
699
debug ( 'finish' , e , ret ) ;
700
+
701
+ if ( tmpListeners . length !== 0 ) {
702
+ tmpListeners . forEach ( ( tmp ) => {
703
+ process . removeListener ( 'uncaughtException' , tmp ) ;
704
+ } ) ;
705
+ tmpListeners = [ ] ;
706
+ const err = new ERR_INVALID_REPL_INPUT (
707
+ 'Unhandled exception listeners can not be used in the REPL' ) ;
708
+ self . _domain . emit ( 'error' , err ) ;
709
+ if ( ret === process ) {
710
+ self . clearBufferedCommand ( ) ;
711
+ self . displayPrompt ( ) ;
712
+ return ;
713
+ }
714
+ }
715
+ currentListeners = [ ] ;
716
+ checkUncaught = false ;
717
+
673
718
_memory . call ( self , cmd ) ;
674
719
675
720
if ( e && ! self [ kBufferedCommandSymbol ] && cmd . trim ( ) . startsWith ( 'npm ' ) ) {
0 commit comments