()
| 164 | // or this function should take extra care of the async hooks before it |
| 165 | // schedules a setImmediate. |
| 166 | function createOnGlobalUncaughtException() { |
| 167 | // The C++ land node::errors::TriggerUncaughtException() will |
| 168 | // exit the process if it returns false, and continue execution if it |
| 169 | // returns true (which indicates that the exception is handled by the user). |
| 170 | return (er, fromPromise) => { |
| 171 | // It's possible that defaultTriggerAsyncId was set for a constructor |
| 172 | // call that threw and was never cleared. So clear it now. |
| 173 | clearDefaultTriggerAsyncId(); |
| 174 | |
| 175 | const type = fromPromise ? 'unhandledRejection' : 'uncaughtException'; |
| 176 | process.emit('uncaughtExceptionMonitor', er, type); |
| 177 | // Primary callback (e.g., domain) has priority and always handles the exception |
| 178 | if (exceptionHandlerState.captureFn !== null) { |
| 179 | exceptionHandlerState.captureFn(er); |
| 180 | } else { |
| 181 | // If no primary callback, try auxiliary callbacks (e.g., REPL) |
| 182 | // They must return true to indicate handling |
| 183 | let handled = false; |
| 184 | for (let i = exceptionHandlerState.auxiliaryCallbacks.length - 1; i >= 0; i--) { |
| 185 | if (exceptionHandlerState.auxiliaryCallbacks[i](er) === true) { |
| 186 | handled = true; |
| 187 | break; |
| 188 | } |
| 189 | } |
| 190 | if (!handled && !process.emit('uncaughtException', er, type)) { |
| 191 | // If someone handled it, then great. Otherwise, die in C++ land |
| 192 | // since that means that we'll exit the process, emit the 'exit' event. |
| 193 | try { |
| 194 | if (!process._exiting) { |
| 195 | process._exiting = true; |
| 196 | process.exitCode = kGenericUserError; |
| 197 | process.emit('exit', kGenericUserError); |
| 198 | } |
| 199 | } catch { |
| 200 | // Nothing to be done about it at this point. |
| 201 | } |
| 202 | return false; |
| 203 | } |
| 204 | } |
| 205 | |
| 206 | // If we handled an error, then make sure any ticks get processed |
| 207 | // by ensuring that the next Immediate cycle isn't empty. |
| 208 | require('timers').setImmediate(noop); |
| 209 | |
| 210 | // Emit the after() hooks now that the exception has been handled. |
| 211 | if (afterHooksExist()) { |
| 212 | do { |
| 213 | const asyncId = executionAsyncId(); |
| 214 | if (asyncId === 0) |
| 215 | popAsyncContext(0); |
| 216 | else |
| 217 | emitAfter(asyncId); |
| 218 | } while (hasAsyncIdStack()); |
| 219 | } |
| 220 | // And completely empty the id stack, including anything that may be |
| 221 | // cached on the native side. |
| 222 | clearAsyncIdStack(); |
| 223 |
no test coverage detected
searching dependent graphs…