Skip to content

Commit

Permalink
Merge pull request #8507 from electron/fix-node-upgrade-patches
Browse files Browse the repository at this point in the history
Redo node 7.4 error handling patch
  • Loading branch information
kevinsawicki authored Jan 26, 2017
2 parents a4e25a8 + 06c0250 commit 2ee5f6f
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 16 deletions.
10 changes: 7 additions & 3 deletions atom/common/node_bindings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,13 @@ node::Environment* NodeBindings::CreateEnvironment(
new node::IsolateData(context->GetIsolate(), uv_default_loop()), context,
args.size(), c_argv.get(), 0, nullptr);

// Node uses the deprecated SetAutorunMicrotasks(false) mode, we should switch
// to use the scoped policy to match blink's behavior.
if (!is_browser_) {
if (is_browser_) {
// SetAutorunMicrotasks is no longer called in node::CreateEnvironment
// so instead call it here to match expected node behavior
context->GetIsolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
} else {
// Node uses the deprecated SetAutorunMicrotasks(false) mode, we should
// switch to use the scoped policy to match blink's behavior.
context->GetIsolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kScoped);
}

Expand Down
37 changes: 25 additions & 12 deletions spec/node-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const ChildProcess = require('child_process')
const fs = require('fs')
const path = require('path')
const os = require('os')
const {remote} = require('electron')
const {ipcRenderer, remote} = require('electron')

const isCI = remote.getGlobal('isCi')

Expand Down Expand Up @@ -130,26 +130,39 @@ describe('node feature', function () {
})
})

describe('throw error in node context', function () {
it('gets caught', function (done) {
var error = new Error('boo!')
var lsts = process.listeners('uncaughtException')
describe('error thrown in renderer process node context', function () {
it('gets emitted as a process uncaughtException event', function (done) {
const error = new Error('boo!')
const listeners = process.listeners('uncaughtException')
process.removeAllListeners('uncaughtException')
process.on('uncaughtException', function () {
var i, len, lst
process.on('uncaughtException', (thrown) => {
assert.strictEqual(thrown, error)
process.removeAllListeners('uncaughtException')
for (i = 0, len = lsts.length; i < len; i++) {
lst = lsts[i]
process.on('uncaughtException', lst)
}
listeners.forEach((listener) => {
process.on('uncaughtException', listener)
})
done()
})
fs.readFile(__filename, function () {
fs.readFile(__filename, () => {
throw error
})
})
})

describe('error thrown in main process node context', function () {
it('gets emitted as a process uncaughtException event', function () {
const error = ipcRenderer.sendSync('handle-uncaught-exception', 'hello')
assert.equal(error, 'hello')
})
})

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)
Expand Down
31 changes: 31 additions & 0 deletions spec/static/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -273,3 +273,34 @@ ipcMain.on('try-emit-web-contents-event', (event, id, eventName) => {
listenerCountAfter
}
})

ipcMain.on('handle-uncaught-exception', (event, message) => {
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)
})
}
2 changes: 1 addition & 1 deletion vendor/node
Submodule node updated 1 files
+7 −4 src/node.cc

0 comments on commit 2ee5f6f

Please sign in to comment.