fix(runtime-core): should catch dom prop set TypeErrors

based on #1051
This commit is contained in:
Evan You 2020-05-01 18:47:27 -04:00
parent c5e7d8b532
commit 98bee596bd
2 changed files with 30 additions and 1 deletions

View File

@ -1,7 +1,10 @@
import { patchProp } from '../src/patchProp' import { patchProp } from '../src/patchProp'
import { render, h } from '../src' import { render, h } from '../src'
import { mockWarn } from '@vue/shared'
describe('runtime-dom: props patching', () => { describe('runtime-dom: props patching', () => {
mockWarn()
test('basic', () => { test('basic', () => {
const el = document.createElement('div') const el = document.createElement('div')
patchProp(el, 'id', null, 'foo') patchProp(el, 'id', null, 'foo')
@ -92,4 +95,16 @@ describe('runtime-dom: props patching', () => {
patchProp(el, 'srcObject', null, null) patchProp(el, 'srcObject', null, null)
expect(el.srcObject).toBe(intiialValue) expect(el.srcObject).toBe(intiialValue)
}) })
test('catch and warn prop set TypeError', () => {
const el = document.createElement('div')
Object.defineProperty(el, 'someProp', {
set() {
throw new TypeError('Invalid type')
}
})
patchProp(el, 'someProp', null, 'foo')
expect(`Failed setting prop "someProp" on <div>`).toHaveBeenWarnedLast()
})
}) })

View File

@ -1,6 +1,9 @@
// __UNSAFE__ // __UNSAFE__
// Reason: potentially setting innerHTML. // Reason: potentially setting innerHTML.
// This can come from explicit usage of v-html or innerHTML as a prop in render // This can come from explicit usage of v-html or innerHTML as a prop in render
import { warn } from '@vue/runtime-core'
// functions. The user is reponsible for using them with only trusted content. // functions. The user is reponsible for using them with only trusted content.
export function patchDOMProp( export function patchDOMProp(
el: any, el: any,
@ -35,6 +38,17 @@ export function patchDOMProp(
// e.g. <div :id="null"> // e.g. <div :id="null">
el[key] = '' el[key] = ''
} else { } else {
el[key] = value // some properties perform value validation and throw
try {
el[key] = value
} catch (e) {
if (__DEV__) {
warn(
`Failed setting prop "${key}" on <${el.tagName.toLowerCase()}>: ` +
`value ${value} is invalid.`,
e
)
}
}
} }
} }