@@ -77,6 +77,20 @@ Domain.prototype._disposed = undefined;
77
77
// Called by process._fatalException in case an error was thrown.
78
78
Domain . prototype . _errorHandler = function errorHandler ( er ) {
79
79
var caught = false ;
80
+ var self = this ;
81
+
82
+ function emitError ( ) {
83
+ var handled = self . emit ( 'error' , er ) ;
84
+
85
+ // Exit all domains on the stack. Uncaught exceptions end the
86
+ // current tick and no domains should be left on the stack
87
+ // between ticks.
88
+ stack . length = 0 ;
89
+ exports . active = process . domain = null ;
90
+
91
+ return handled ;
92
+ }
93
+
80
94
// ignore errors on disposed domains.
81
95
//
82
96
// XXX This is a bit stupid. We should probably get rid of
@@ -89,38 +103,54 @@ Domain.prototype._errorHandler = function errorHandler(er) {
89
103
er . domain = this ;
90
104
er . domainThrown = true ;
91
105
}
92
- // wrap this in a try/catch so we don't get infinite throwing
93
- try {
94
- // One of three things will happen here.
95
- //
96
- // 1. There is a handler, caught = true
97
- // 2. There is no handler, caught = false
98
- // 3. It throws, caught = false
99
- //
100
- // If caught is false after this, then there's no need to exit()
101
- // the domain, because we're going to crash the process anyway.
102
- caught = this . emit ( 'error' , er ) ;
103
106
104
- // Exit all domains on the stack. Uncaught exceptions end the
105
- // current tick and no domains should be left on the stack
106
- // between ticks.
107
- stack . length = 0 ;
108
- exports . active = process . domain = null ;
109
- } catch ( er2 ) {
110
- // The domain error handler threw! oh no!
111
- // See if another domain can catch THIS error,
112
- // or else crash on the original one.
113
- // If the user already exited it, then don't double-exit.
114
- if ( this === exports . active ) {
115
- stack . pop ( ) ;
107
+ // The top-level domain-handler is handled separately.
108
+ //
109
+ // The reason is that if V8 was passed a command line option
110
+ // asking it to abort on an uncaught exception (currently
111
+ // "--abort-on-uncaught-exception"), we want an uncaught exception
112
+ // in the top-level domain error handler to make the
113
+ // process abort. Using try/catch here would always make V8 think
114
+ // that these exceptions are caught, and thus would prevent it from
115
+ // aborting in these cases.
116
+ if ( stack . length === 1 ) {
117
+ try {
118
+ // Set the _emittingTopLevelDomainError so that we know that, even
119
+ // if technically the top-level domain is still active, it would
120
+ // be ok to abort on an uncaught exception at this point
121
+ process . _emittingTopLevelDomainError = true ;
122
+ caught = emitError ( ) ;
123
+ } finally {
124
+ process . _emittingTopLevelDomainError = false ;
116
125
}
117
- if ( stack . length ) {
118
- exports . active = process . domain = stack [ stack . length - 1 ] ;
119
- caught = process . _fatalException ( er2 ) ;
120
- } else {
121
- caught = false ;
126
+ } else {
127
+ // wrap this in a try/catch so we don't get infinite throwing
128
+ try {
129
+ // One of three things will happen here.
130
+ //
131
+ // 1. There is a handler, caught = true
132
+ // 2. There is no handler, caught = false
133
+ // 3. It throws, caught = false
134
+ //
135
+ // If caught is false after this, then there's no need to exit()
136
+ // the domain, because we're going to crash the process anyway.
137
+ caught = emitError ( ) ;
138
+ } catch ( er2 ) {
139
+ // The domain error handler threw! oh no!
140
+ // See if another domain can catch THIS error,
141
+ // or else crash on the original one.
142
+ // If the user already exited it, then don't double-exit.
143
+ if ( this === exports . active ) {
144
+ stack . pop ( ) ;
145
+ }
146
+ if ( stack . length ) {
147
+ exports . active = process . domain = stack [ stack . length - 1 ] ;
148
+ caught = process . _fatalException ( er2 ) ;
149
+ } else {
150
+ caught = false ;
151
+ }
152
+ return caught ;
122
153
}
123
- return caught ;
124
154
}
125
155
return caught ;
126
156
} ;
0 commit comments