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
}
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.
const unwrapArgs = function (sender: electron.WebContents, frameId: number, contextId: string, args: any[]) {
const metaToValue = function (meta: MetaTypeFromRenderer): any {
@ -262,8 +273,9 @@ const unwrapArgs = function (sender: electron.WebContents, frameId: number, cont
then: metaToValue(meta.then)
})
case 'object': {
const ret: any = {}
Object.defineProperty(ret.constructor, 'name', { value: meta.name })
const ret: any = meta.name !== 'Object' ? Object.create({
constructor: fakeConstructor(Object, meta.name)
}) : {}
for (const { name, value } of meta.members) {
ret[name] = metaToValue(value)

View file

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

View file

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