Merge pull request #11158 from electron/execute-errors

fix: Pass on errors thrown in `executeJavaScript`
This commit is contained in:
Charles Kerr 2017-11-20 09:14:05 -06:00 committed by GitHub
commit 5eb00e45aa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 1 deletions

View file

@ -112,6 +112,16 @@ const webFrameMethods = [
] ]
const webFrameMethodsWithResult = [] const webFrameMethodsWithResult = []
const errorConstructors = {
Error,
EvalError,
RangeError,
ReferenceError,
SyntaxError,
TypeError,
URIError
}
const asyncWebFrameMethods = function (requestId, method, callback, ...args) { const asyncWebFrameMethods = function (requestId, method, callback, ...args) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.send('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', requestId, method, args) this.send('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', requestId, method, args)
@ -120,7 +130,14 @@ const asyncWebFrameMethods = function (requestId, method, callback, ...args) {
if (typeof callback === 'function') callback(result) if (typeof callback === 'function') callback(result)
resolve(result) resolve(result)
} else { } else {
reject(error) if (error.__ELECTRON_SERIALIZED_ERROR__ && errorConstructors[error.name]) {
const rehydratedError = new errorConstructors[error.name](error.message)
rehydratedError.stack = error.stack
reject(rehydratedError)
} else {
reject(error)
}
} }
}) })
}) })

View file

@ -45,6 +45,17 @@ electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', (ev
event.sender.send(`ELECTRON_INTERNAL_BROWSER_ASYNC_WEB_FRAME_RESPONSE_${requestId}`, null, resolvedResult) event.sender.send(`ELECTRON_INTERNAL_BROWSER_ASYNC_WEB_FRAME_RESPONSE_${requestId}`, null, resolvedResult)
}) })
.catch((resolvedError) => { .catch((resolvedError) => {
if (resolvedError instanceof Error) {
// Errors get lost, because: JSON.stringify(new Error('Message')) === {}
// Take the serializable properties and construct a generic object
resolvedError = {
message: resolvedError.message,
stack: resolvedError.stack,
name: resolvedError.name,
__ELECTRON_SERIALIZED_ERROR__: true
}
}
event.sender.send(`ELECTRON_INTERNAL_BROWSER_ASYNC_WEB_FRAME_RESPONSE_${requestId}`, resolvedError) event.sender.send(`ELECTRON_INTERNAL_BROWSER_ASYNC_WEB_FRAME_RESPONSE_${requestId}`, resolvedError)
}) })
} }

View file

@ -2514,6 +2514,15 @@ describe('BrowserWindow module', () => {
const code = `(() => "${expected}")()` const code = `(() => "${expected}")()`
const asyncCode = `(() => new Promise(r => setTimeout(() => r("${expected}"), 500)))()` const asyncCode = `(() => new Promise(r => setTimeout(() => r("${expected}"), 500)))()`
const badAsyncCode = `(() => new Promise((r, e) => setTimeout(() => e("${expectedErrorMsg}"), 500)))()` const badAsyncCode = `(() => new Promise((r, e) => setTimeout(() => e("${expectedErrorMsg}"), 500)))()`
const errorTypes = new Set([
Error,
ReferenceError,
EvalError,
RangeError,
SyntaxError,
TypeError,
URIError
])
it('doesnt throw when no calback is provided', () => { it('doesnt throw when no calback is provided', () => {
const result = ipcRenderer.sendSync('executeJavaScript', code, false) const result = ipcRenderer.sendSync('executeJavaScript', code, false)
@ -2561,6 +2570,17 @@ describe('BrowserWindow module', () => {
done() done()
}) })
}) })
it('rejects the returned promise with an error if an Error.prototype is thrown', async () => {
for (const error in errorTypes) {
await new Promise((resolve) => {
ipcRenderer.send('executeJavaScript', `Promise.reject(new ${error.name}("Wamp-wamp")`, true)
ipcRenderer.once('executeJavaScript-promise-error-name', (event, name) => {
assert.equal(name, error.name)
resolve()
})
})
}
})
it('works after page load and during subframe load', (done) => { it('works after page load and during subframe load', (done) => {
w.webContents.once('did-finish-load', () => { w.webContents.once('did-finish-load', () => {
// initiate a sub-frame load, then try and execute script during it // initiate a sub-frame load, then try and execute script during it

View file

@ -217,6 +217,10 @@ app.on('ready', function () {
window.webContents.send('executeJavaScript-promise-response', result) window.webContents.send('executeJavaScript-promise-response', result)
}).catch((error) => { }).catch((error) => {
window.webContents.send('executeJavaScript-promise-error', error) window.webContents.send('executeJavaScript-promise-error', error)
if (error && error.name) {
window.webContents.send('executeJavaScript-promise-error-name', error.name)
}
}) })
if (!hasCallback) { if (!hasCallback) {