Browse Source

fix: don't double-log unhandled rejections (#37464)

Shelley Vohr 2 years ago
parent
commit
829fb4f586

+ 1 - 1
shell/browser/electron_browser_main_parts.cc

@@ -279,7 +279,7 @@ void ElectronBrowserMainParts::PostEarlyInitialization() {
   env->set_trace_sync_io(env->options()->trace_sync_io);
 
   // We do not want to crash the main process on unhandled rejections.
-  env->options()->unhandled_rejections = "warn";
+  env->options()->unhandled_rejections = "warn-with-error-code";
 
   // Add Electron extended APIs.
   electron_bindings_->BindTo(js_env_->isolate(), env->process_object());

+ 1 - 1
shell/renderer/electron_renderer_client.cc

@@ -96,7 +96,7 @@ void ElectronRendererClient::DidCreateScriptContext(
   env->options()->force_context_aware = true;
 
   // We do not want to crash the renderer process on unhandled rejections.
-  env->options()->unhandled_rejections = "warn";
+  env->options()->unhandled_rejections = "warn-with-error-code";
 
   environments_.insert(env);
 

+ 13 - 0
spec/fixtures/api/unhandled-rejection-handled.js

@@ -0,0 +1,13 @@
+const { app } = require('electron');
+
+const handleUnhandledRejection = (reason) => {
+  console.error(`Unhandled Rejection: ${reason.stack}`);
+  app.quit();
+};
+
+const main = async () => {
+  process.on('unhandledRejection', handleUnhandledRejection);
+  throw new Error('oops');
+};
+
+main();

+ 5 - 0
spec/fixtures/api/unhandled-rejection.js

@@ -0,0 +1,5 @@
+const main = async () => {
+  throw new Error('oops');
+};
+
+main();

+ 36 - 0
spec/node-spec.ts

@@ -226,6 +226,42 @@ describe('node feature', () => {
         }));
         expect(result).to.equal('hello');
       });
+
+      it('does not log the warning more than once when the rejection is unhandled', async () => {
+        const appPath = path.join(mainFixturesPath, 'api', 'unhandled-rejection.js');
+        const appProcess = childProcess.spawn(process.execPath, [appPath]);
+
+        let output = '';
+        const out = (data: string) => {
+          output += data;
+          if (/UnhandledPromiseRejectionWarning/.test(data)) {
+            appProcess.kill();
+          }
+        };
+        appProcess.stdout!.on('data', out);
+        appProcess.stderr!.on('data', out);
+
+        await once(appProcess, 'exit');
+        expect(/UnhandledPromiseRejectionWarning/.test(output)).to.equal(true);
+        const matches = output.match(/Error: oops/gm);
+        expect(matches).to.have.lengthOf(1);
+      });
+
+      it('does not log the warning more than once when the rejection is handled', async () => {
+        const appPath = path.join(mainFixturesPath, 'api', 'unhandled-rejection-handled.js');
+        const appProcess = childProcess.spawn(process.execPath, [appPath]);
+
+        let output = '';
+        const out = (data: string) => { output += data; };
+        appProcess.stdout!.on('data', out);
+        appProcess.stderr!.on('data', out);
+
+        const [code] = await once(appProcess, 'exit');
+        expect(code).to.equal(0);
+        expect(/UnhandledPromiseRejectionWarning/.test(output)).to.equal(false);
+        const matches = output.match(/Error: oops/gm);
+        expect(matches).to.have.lengthOf(1);
+      });
     });
   });