Browse Source

Add spec for unhandledRejection event in main process

Kevin Sawicki 8 years ago
parent
commit
1004d205d8
2 changed files with 31 additions and 8 deletions
  1. 8 1
      spec/node-spec.js
  2. 23 7
      spec/static/main.js

+ 8 - 1
spec/node-spec.js

@@ -131,7 +131,7 @@ describe('node feature', function () {
     })
 
     describe('error thrown in renderer process node context', function () {
-      it('gets emitted as an process uncaughtException event', function (done) {
+      it('gets emitted as a process uncaughtException event', function (done) {
         const error = new Error('boo!')
         const listeners = process.listeners('uncaughtException')
         process.removeAllListeners('uncaughtException')
@@ -156,6 +156,13 @@ describe('node feature', function () {
       })
     })
 
+    describe('promise rejection in main process node context', function () {
+      it('gets emitted as a process unhandledRejection event', function () {
+        const error = ipcRenderer.sendSync('handle-unhandled-rejection', 'hello')
+        assert.equal(error, 'hello')
+      })
+    })
+
     describe('setTimeout called under Chromium event loop in browser process', function () {
       it('can be scheduled in time', function (done) {
         remote.getGlobal('setTimeout')(done, 0)

+ 23 - 7
spec/static/main.js

@@ -275,16 +275,32 @@ ipcMain.on('try-emit-web-contents-event', (event, id, eventName) => {
 })
 
 ipcMain.on('handle-uncaught-exception', (event, message) => {
-  const listeners = process.listeners('uncaughtException')
-  process.removeAllListeners('uncaughtException')
-  process.on('uncaughtException', (error) => {
-    process.removeAllListeners('uncaughtException')
-    listeners.forEach((listener) => {
-      process.on('uncaughtException', listener)
-    })
+  suspendListeners(process, 'uncaughtException', (error) => {
     event.returnValue = error.message
   })
   fs.readFile(__filename, () => {
     throw new Error(message)
   })
 })
+
+ipcMain.on('handle-unhandled-rejection', (event, message) => {
+  suspendListeners(process, 'unhandledRejection', (error) => {
+    event.returnValue = error.message
+  })
+  fs.readFile(__filename, () => {
+    Promise.reject(new Error(message))
+  })
+})
+
+// Suspend listeners until the next event and then restore them
+const suspendListeners = (emitter, eventName, callback) => {
+  const listeners = emitter.listeners(eventName)
+  emitter.removeAllListeners(eventName)
+  emitter.once(eventName, (...args) => {
+    emitter.removeAllListeners(eventName)
+    listeners.forEach((listener) => {
+      emitter.on(eventName, listener)
+    })
+    callback(...args)
+  })
+}