fix: don't overwrite global constructor names in remote (#20637)

* fix: don't overwrite global constructor names in remote

* fake constructor names better, and improve error serialization
This commit is contained in:
Jeremy Apthorp 2019-10-20 23:48:03 -07:00 committed by Cheng Zhao
parent 820dab295f
commit b155ebeeb3
3 changed files with 26 additions and 10 deletions

View file

@ -245,6 +245,17 @@ type MetaTypeFromRenderer = {
length: number length: number
} }
const fakeConstructor = (constructor: Function, name: string) =>
new Proxy(Object, {
get (target, prop, receiver) {
if (prop === 'name') {
return name
} else {
return Reflect.get(target, prop, receiver)
}
}
})
// Convert array of meta data from renderer into array of real values. // Convert array of meta data from renderer into array of real values.
const unwrapArgs = function (sender: electron.WebContents, frameId: number, contextId: string, args: any[]) { const unwrapArgs = function (sender: electron.WebContents, frameId: number, contextId: string, args: any[]) {
const metaToValue = function (meta: MetaTypeFromRenderer): any { const metaToValue = function (meta: MetaTypeFromRenderer): any {
@ -262,8 +273,9 @@ const unwrapArgs = function (sender: electron.WebContents, frameId: number, cont
then: metaToValue(meta.then) then: metaToValue(meta.then)
}) })
case 'object': { case 'object': {
const ret: any = {} const ret: any = meta.name !== 'Object' ? Object.create({
Object.defineProperty(ret.constructor, 'name', { value: meta.name }) constructor: fakeConstructor(Object, meta.name)
}) : {}
for (const { name, value } of meta.members) { for (const { name, value } of meta.members) {
ret[name] = metaToValue(value) ret[name] = metaToValue(value)

View file

@ -64,6 +64,11 @@ function wrapArgs (args, visited = new Set()) {
type: 'remote-object', type: 'remote-object',
id: v8Util.getHiddenValue(value, 'atomId') id: v8Util.getHiddenValue(value, 'atomId')
} }
} else if (value instanceof Error) {
return {
type: 'value',
value
}
} }
const meta = { const meta = {

View file

@ -498,17 +498,16 @@ ifdescribe(features.isRemoteModuleEnabled())('remote module', () => {
it('throws errors from the main process', () => { it('throws errors from the main process', () => {
expect(() => { expect(() => {
throwFunction() throwFunction()
}).to.throw() }).to.throw(/undefined/)
}) })
it('throws custom errors from the main process', () => { it('tracks error cause', () => {
const err = new Error('error')
err.cause = new Error('cause')
err.prop = 'error prop'
try { try {
throwFunction(err) throwFunction(new Error('error from main'))
} catch (error) { expect.fail()
expect(error.cause).to.deep.equal(...resolveGetters(err)) } catch (e) {
expect(e.message).to.match(/Could not call remote function/)
expect(e.cause.message).to.equal('error from main')
} }
}) })
}) })