Skip to content

Commit

Permalink
fix(watch): errors thrown in the asynchronous callback function in wa…
Browse files Browse the repository at this point in the history
…tch will not be caught. (#751)
  • Loading branch information
ygj6 committed Jul 7, 2021
1 parent a279eab commit f0e423f
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 8 deletions.
10 changes: 5 additions & 5 deletions src/apis/watch.ts
Expand Up @@ -235,14 +235,14 @@ function createWatcher(
) {
return fn
}
return (((...args: any[]) =>
return ((...args: any[]) =>
queueFlushJob(
vm,
() => {
fn(...args)
},
flushMode as 'pre' | 'post'
)) as any) as T
)) as any as T
}

// effect watch
Expand Down Expand Up @@ -320,7 +320,7 @@ function createWatcher(
const applyCb = (n: any, o: any) => {
// cleanup before running cb again
runCleanup()
cb(n, o, registerCleanup)
return cb(n, o, registerCleanup)
}
let callback = createScheduler(applyCb)
if (options.immediate) {
Expand All @@ -330,10 +330,10 @@ function createWatcher(
let shiftCallback = (n: any, o: any) => {
shiftCallback = originalCallback
// o is undefined on the first call
applyCb(n, isArray(n) ? [] : o)
return applyCb(n, isArray(n) ? [] : o)
}
callback = (n: any, o: any) => {
shiftCallback(n, o)
return shiftCallback(n, o)
}
}

Expand Down
32 changes: 31 additions & 1 deletion test/apis/watch.spec.js
@@ -1,7 +1,16 @@
const Vue = require('vue/dist/vue.common.js')
const { ref, reactive, watch, watchEffect, set } = require('../../src')
const {
ref,
reactive,
watch,
watchEffect,
set,
nextTick,
} = require('../../src')
const { mockWarn } = require('../helpers')

describe('api/watch', () => {
mockWarn(true)
const anyFn = expect.any(Function)
let spy
beforeEach(() => {
Expand Down Expand Up @@ -587,6 +596,27 @@ describe('api/watch', () => {
expect(spy).toHaveBeenNthCalledWith(2, [3, 1], [2, 1])
expect(spy).toHaveBeenNthCalledWith(3, [3, 3], [3, 1])
})

it('config.errorHandler should capture render errors', async () => {
new Vue({
setup() {
const a = ref(1)
watch(
a,
async () => {
throw new Error('userWatcherCallback error')
},
{ immediate: true }
)
return {
a,
}
},
template: `<div>{{a}}</div>`,
}).$mount()
await nextTick()
expect(`userWatcherCallback error`).toHaveBeenWarned()
})
})

describe('Out of setup', () => {
Expand Down
4 changes: 2 additions & 2 deletions test/helpers/mockWarn.ts
Expand Up @@ -15,7 +15,7 @@ export function mockWarn(asError = false) {
toHaveBeenWarned(received: string) {
asserted.add(received)
const passed = warn.mock.calls.some(
(args) => args[0].indexOf(received) > -1
(args) => args[0].toString().indexOf(received) > -1
)
if (passed) {
return {
Expand Down Expand Up @@ -91,7 +91,7 @@ export function mockWarn(asError = false) {
.map((args) => args[0])
.filter((received) => {
return !assertedArray.some((assertedMsg) => {
return received.indexOf(assertedMsg) > -1
return received.toString().indexOf(assertedMsg) > -1
})
})
warn.mockRestore()
Expand Down

0 comments on commit f0e423f

Please sign in to comment.