| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent b07cb48 commit 22cd537
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -119,8 +119,8 @@ added: v11.0.0 | |||
| 119 | 119 | * `callback` {Function} Function to be queued. | |
| 120 | 120 | ||
| 121 | 121 | The `queueMicrotask()` method queues a microtask to invoke `callback`. If | |
| 122 | - `callback` throws an exception, the [`process` object][] `'error'` event will | ||
| 123 | - be emitted. | ||
| 122 | + `callback` throws an exception, the [`process` object][] `'uncaughtException'` | ||
| 123 | + event will be emitted. | ||
| 124 | 124 | ||
| 125 | 125 | In general, `queueMicrotask` is the idiomatic choice over `process.nextTick()`. | |
| 126 | 126 | `process.nextTick()` will always run before the microtask queue, and so | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -24,7 +24,8 @@ | |||
| 24 | 24 | _umask, _initgroups, _setegid, _seteuid, | |
| 25 | 25 | _setgid, _setuid, _setgroups, | |
| 26 | 26 | _shouldAbortOnUncaughtToggle }, | |
| 27 | - { internalBinding, NativeModule }) { | ||
| 27 | + { internalBinding, NativeModule }, | ||
| 28 | + triggerFatalException) { | ||
| 28 | 29 | const exceptionHandlerState = { captureFn: null }; | |
| 29 | 30 | const isMainThread = internalBinding('worker').threadId === 0; | |
| 30 | 31 | ||
@@ -538,8 +539,9 @@ | |||
| 538 | 539 | get: () => { | |
| 539 | 540 | process.emitWarning('queueMicrotask() is experimental.', | |
| 540 | 541 | 'ExperimentalWarning'); | |
| 541 | - const { queueMicrotask } = | ||
| 542 | + const { setupQueueMicrotask } = | ||
| 542 | 543 | NativeModule.require('internal/queue_microtask'); | |
| 544 | + const queueMicrotask = setupQueueMicrotask(triggerFatalException); | ||
| 543 | 545 | Object.defineProperty(global, 'queueMicrotask', { | |
| 544 | 546 | value: queueMicrotask, | |
| 545 | 547 | writable: true, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,27 +5,35 @@ const { AsyncResource } = require('async_hooks'); | |||
| 5 | 5 | const { getDefaultTriggerAsyncId } = require('internal/async_hooks'); | |
| 6 | 6 | const { enqueueMicrotask } = internalBinding('util'); | |
| 7 | 7 | ||
| 8 | - // declared separately for name, arrow function to prevent construction | ||
| 9 | - const queueMicrotask = (callback) => { | ||
| 10 | - if (typeof callback !== 'function') { | ||
| 11 | - throw new ERR_INVALID_ARG_TYPE('callback', 'function', callback); | ||
| 12 | - } | ||
| 8 | + const setupQueueMicrotask = (triggerFatalException) => { | ||
| 9 | + const queueMicrotask = (callback) => { | ||
| 10 | + if (typeof callback !== 'function') { | ||
| 11 | + throw new ERR_INVALID_ARG_TYPE('callback', 'function', callback); | ||
| 12 | + } | ||
| 13 | 13 | ||
| 14 | - const asyncResource = new AsyncResource('Microtask', { | ||
| 15 | - triggerAsyncId: getDefaultTriggerAsyncId(), | ||
| 16 | - requireManualDestroy: true, | ||
| 17 | - }); | ||
| 14 | + const asyncResource = new AsyncResource('Microtask', { | ||
| 15 | + triggerAsyncId: getDefaultTriggerAsyncId(), | ||
| 16 | + requireManualDestroy: true, | ||
| 17 | + }); | ||
| 18 | 18 | ||
| 19 | - enqueueMicrotask(() => { | ||
| 20 | - asyncResource.runInAsyncScope(() => { | ||
| 21 | - try { | ||
| 22 | - callback(); | ||
| 23 | - } catch (e) { | ||
| 24 | - process.emit('error', e); | ||
| 25 | - } | ||
| 19 | + enqueueMicrotask(() => { | ||
| 20 | + asyncResource.runInAsyncScope(() => { | ||
| 21 | + try { | ||
| 22 | + callback(); | ||
| 23 | + } catch (error) { | ||
| 24 | + // TODO(devsnek) remove this if | ||
| 25 | + // https://bugs.chromium.org/p/v8/issues/detail?id=8326 | ||
| 26 | + // is resolved such that V8 triggers the fatal exception | ||
| 27 | + // handler for microtasks | ||
| 28 | + triggerFatalException(error); | ||
| 29 | + } finally { | ||
| 30 | + asyncResource.emitDestroy(); | ||
| 31 | + } | ||
| 32 | + }); | ||
| 26 | 33 | }); | |
| 27 | - asyncResource.emitDestroy(); | ||
| 28 | - }); | ||
| 34 | + }; | ||
| 35 | + | ||
| 36 | + return queueMicrotask; | ||
| 29 | 37 | }; | |
| 30 | 38 | ||
| 31 | - module.exports = { queueMicrotask }; | ||
| 39 | + module.exports = { setupQueueMicrotask }; | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1423,6 +1423,18 @@ void FatalException(Isolate* isolate, const TryCatch& try_catch) { | |||
| 1423 | 1423 | } | |
| 1424 | 1424 | ||
| 1425 | 1425 | ||
| 1426 | + static void FatalException(const FunctionCallbackInfo<Value>& args) { | ||
| 1427 | + Isolate* isolate = args.GetIsolate(); | ||
| 1428 | + Environment* env = Environment::GetCurrent(isolate); | ||
| 1429 | + if (env != nullptr && env->abort_on_uncaught_exception()) { | ||
| 1430 | + Abort(); | ||
| 1431 | + } | ||
| 1432 | + Local<Value> exception = args[0]; | ||
| 1433 | + Local<Message> message = Exception::CreateMessage(isolate, exception); | ||
| 1434 | + FatalException(isolate, exception, message); | ||
| 1435 | + } | ||
| 1436 | + | ||
| 1437 | + | ||
| 1426 | 1438 | static void OnMessage(Local<Message> message, Local<Value> error) { | |
| 1427 | 1439 | // The current version of V8 sends messages for errors only | |
| 1428 | 1440 | // (thus `error` is always set). | |
@@ -2161,14 +2173,19 @@ void LoadEnvironment(Environment* env) { | |||
| 2161 | 2173 | return; | |
| 2162 | 2174 | } | |
| 2163 | 2175 | ||
| 2176 | + Local<Function> trigger_fatal_exception = | ||
| 2177 | + env->NewFunctionTemplate(FatalException)->GetFunction(env->context()) | ||
| 2178 | + .ToLocalChecked(); | ||
| 2179 | + | ||
| 2164 | 2180 | // Bootstrap Node.js | |
| 2165 | 2181 | Local<Object> bootstrapper = Object::New(env->isolate()); | |
| 2166 | 2182 | SetupBootstrapObject(env, bootstrapper); | |
| 2167 | 2183 | Local<Value> bootstrapped_node; | |
| 2168 | 2184 | Local<Value> node_bootstrapper_args[] = { | |
| 2169 | 2185 | env->process_object(), | |
| 2170 | 2186 | bootstrapper, | |
| 2171 | - bootstrapped_loaders | ||
| 2187 | + bootstrapped_loaders, | ||
| 2188 | + trigger_fatal_exception, | ||
| 2172 | 2189 | }; | |
| 2173 | 2190 | if (!ExecuteBootstrapper(env, node_bootstrapper.ToLocalChecked(), | |
| 2174 | 2191 | arraysize(node_bootstrapper_args), | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -42,7 +42,7 @@ queueMicrotask(common.mustCall(function() { | |||
| 42 | 42 | } | |
| 43 | 43 | ||
| 44 | 44 | const eq = []; | |
| 45 | - process.on('error', (e) => { | ||
| 45 | + process.on('uncaughtException', (e) => { | ||
| 46 | 46 | eq.push(e); | |
| 47 | 47 | }); | |
| 48 | 48 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments