diff --git a/shell/app/node_main.cc b/shell/app/node_main.cc index 56a17878df355..4391189e7c6f8 100644 --- a/shell/app/node_main.cc +++ b/shell/app/node_main.cc @@ -78,6 +78,7 @@ int NodeMain(int argc, char* argv[]) { // Initialize gin::IsolateHolder. JavascriptEnvironment gin_env(loop); + gin_env.isolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit); node::IsolateData* isolate_data = node::CreateIsolateData(gin_env.isolate(), loop, gin_env.platform()); diff --git a/spec/fixtures/module/node-promise-timer.js b/spec/fixtures/module/node-promise-timer.js new file mode 100644 index 0000000000000..b21c24f5dfc36 --- /dev/null +++ b/spec/fixtures/module/node-promise-timer.js @@ -0,0 +1,23 @@ +const waitMs = (msec) => new Promise((resolve) => setTimeout(resolve, msec)); + +const intervalMsec = 100; +const numIterations = 2; +let curIteration = 0; +let promise; + +for (let i = 0; i < numIterations; i++) { + promise = (promise || waitMs(intervalMsec)).then(() => { + ++curIteration; + return waitMs(intervalMsec); + }); +} + +// https://github.com/electron/electron/issues/21515 was about electron +// exiting before promises finished. This test sets the pending exitCode +// to failure, then resets it to success only if all promises finish. +process.exitCode = 1; +promise.then(() => { + if (curIteration === numIterations) { + process.exitCode = 0; + } +}); diff --git a/spec/node-spec.js b/spec/node-spec.js index 0275a53336bfc..b11cad14da8a8 100644 --- a/spec/node-spec.js +++ b/spec/node-spec.js @@ -690,4 +690,17 @@ describe('node feature', () => { const result = ChildProcess.spawnSync(remote.process.execPath, [path.resolve(fixtures, 'api', 'electron-main-module', 'app.asar')]); expect(result.status).to.equal(0); }); + + it('handles Promise timeouts correctly', (done) => { + const scriptPath = path.join(fixtures, 'module', 'node-promise-timer.js'); + const child = ChildProcess.spawn(process.execPath, [scriptPath], { + env: { ELECTRON_RUN_AS_NODE: 'true' } + }); + emittedOnce(child, 'exit').then(([code, signal]) => { + expect(code).to.equal(0); + expect(signal).to.equal(null); + child.kill(); + done(); + }); + }); });