Skip to content

Commit ae4bd94

Browse files
authored
fix(reactivity): once watcher should stop when its callback throws (#15755)
1 parent 0bea14b commit ae4bd94

2 files changed

Lines changed: 17 additions & 3 deletions

File tree

‎packages/reactivity/__tests__/watch.spec.ts‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,4 +330,16 @@ describe('watch', () => {
330330
value.value = true
331331
expect(value.value).toBe(false)
332332
})
333+
334+
test('once watcher should stop when its callback throws', () => {
335+
const source = ref(0)
336+
const callback = vi.fn(() => {
337+
throw new Error('oops')
338+
})
339+
watch(source, callback, { once: true })
340+
341+
expect(() => (source.value = 1)).toThrow('oops')
342+
expect(() => (source.value = 2)).not.toThrow()
343+
expect(callback).toHaveBeenCalledTimes(1)
344+
})
333345
})

‎packages/reactivity/src/watch.ts‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,11 @@ export function watch(
221221
if (once && cb) {
222222
const _cb = cb
223223
cb = (...args) => {
224-
const res = _cb(...args)
225-
watchHandle()
226-
return res
224+
try {
225+
return _cb(...args)
226+
} finally {
227+
watchHandle()
228+
}
227229
}
228230
}
229231

0 commit comments

Comments
 (0)