Fix missing remote object error when calling remote function created in preload script (3-0-x) (#15445)

* fix: report wrong context error based on contextId

* fix: destroyed remote renderer warning is now async
This commit is contained in:
Cheng Zhao 2018-11-01 08:55:02 +09:00 committed by GitHub
parent 7b0959ed2b
commit 5c853b681c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 52 additions and 20 deletions

View file

@ -148,9 +148,10 @@ const throwRPCError = function (message) {
throw error
}
const removeRemoteListenersAndLogWarning = (sender, meta, callIntoRenderer) => {
const removeRemoteListenersAndLogWarning = (sender, callIntoRenderer) => {
const location = v8Util.getHiddenValue(callIntoRenderer, 'location')
let message = `Attempting to call a function in a renderer window that has been closed or released.` +
`\nFunction provided here: ${meta.location}`
`\nFunction provided here: ${location}`
if (sender instanceof EventEmitter) {
const remoteEvents = sender.eventNames().filter((eventName) => {
@ -213,14 +214,14 @@ const unwrapArgs = function (sender, contextId, args) {
return rendererFunctions.get(objectId)
}
const webContentsId = sender.getId()
let callIntoRenderer = function (...args) {
if (!sender.isDestroyed() && webContentsId === sender.getId()) {
const callIntoRenderer = function (...args) {
if (!sender.isDestroyed()) {
sender.send('ELECTRON_RENDERER_CALLBACK', contextId, meta.id, valueToMeta(sender, contextId, args))
} else {
removeRemoteListenersAndLogWarning(this, meta, callIntoRenderer)
removeRemoteListenersAndLogWarning(this, callIntoRenderer)
}
}
v8Util.setHiddenValue(callIntoRenderer, 'location', meta.location)
Object.defineProperty(callIntoRenderer, 'length', { value: meta.length })
v8Util.setRemoteCallbackFreer(callIntoRenderer, contextId, meta.id, sender)
@ -261,6 +262,15 @@ const callFunction = function (event, contextId, func, caller, args) {
}
}
ipcMain.on('ELECTRON_BROWSER_WRONG_CONTEXT_ERROR', function (event, contextId, passedContextId, id) {
const objectId = [passedContextId, id]
if (!rendererFunctions.has(objectId)) {
// Do nothing if the error has already been reported before.
return
}
removeRemoteListenersAndLogWarning(event.sender, rendererFunctions.get(objectId))
})
ipcMain.on('ELECTRON_BROWSER_REQUIRE', function (event, contextId, module) {
try {
event.returnValue = valueToMeta(event.sender, contextId, process.mainModule.require(module))