Skip to content

Commit dfbc27b

Browse files
fix: ensure cleanup in watcher.get
watcher.get should always clean up observee stack in order to prevent memory leak. Also, non-user defined watch should rethrow error. vuejs#5975
1 parent b5f08f3 commit dfbc27b

File tree

2 files changed

+25
-13
lines changed

2 files changed

+25
-13
lines changed

src/core/observer/watcher.js

+14-13
Original file line numberDiff line numberDiff line change
@@ -94,22 +94,23 @@ export default class Watcher {
9494
pushTarget(this)
9595
let value
9696
const vm = this.vm
97-
if (this.user) {
98-
try {
99-
value = this.getter.call(vm, vm)
100-
} catch (e) {
97+
try {
98+
value = this.getter.call(vm, vm)
99+
} catch (e) {
100+
if (this.user) {
101101
handleError(e, vm, `getter for watcher "${this.expression}"`)
102+
} else {
103+
throw e
102104
}
103-
} else {
104-
value = this.getter.call(vm, vm)
105-
}
106-
// "touch" every property so they are all tracked as
107-
// dependencies for deep watching
108-
if (this.deep) {
109-
traverse(value)
105+
} finally {
106+
// "touch" every property so they are all tracked as
107+
// dependencies for deep watching
108+
if (this.deep) {
109+
traverse(value)
110+
}
111+
popTarget()
112+
this.cleanupDeps()
110113
}
111-
popTarget()
112-
this.cleanupDeps()
113114
return value
114115
}
115116

test/unit/features/options/computed.spec.js

+11
Original file line numberDiff line numberDiff line change
@@ -193,4 +193,15 @@ describe('Options computed', () => {
193193
})
194194
expect(`computed property "a" is already defined as a prop`).toHaveBeenWarned()
195195
})
196+
197+
it('rethrow computed error', () => {
198+
const vm = new Vue({
199+
computed: {
200+
a: () => {
201+
throw new Error('rethrow')
202+
}
203+
}
204+
})
205+
expect(() => vm.a).toThrowError('rethrow')
206+
})
196207
})

0 commit comments

Comments
 (0)