fix(runtime-core): handle error in async setup (#2881)

This commit is contained in:
edison 2021-03-26 22:26:30 +08:00 committed by GitHub
parent abd129d845
commit d668d48e9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 2 deletions

View File

@ -23,7 +23,7 @@ import {
} from './componentProps' } from './componentProps'
import { Slots, initSlots, InternalSlots } from './componentSlots' import { Slots, initSlots, InternalSlots } from './componentSlots'
import { warn } from './warning' import { warn } from './warning'
import { ErrorCodes, callWithErrorHandling } from './errorHandling' import { ErrorCodes, callWithAsyncErrorHandling } from './errorHandling'
import { AppContext, createAppContext, AppConfig } from './apiCreateApp' import { AppContext, createAppContext, AppConfig } from './apiCreateApp'
import { Directive, validateDirectiveName } from './directives' import { Directive, validateDirectiveName } from './directives'
import { import {
@ -579,7 +579,7 @@ function setupStatefulComponent(
currentInstance = instance currentInstance = instance
pauseTracking() pauseTracking()
const setupResult = callWithErrorHandling( const setupResult = callWithAsyncErrorHandling(
setup, setup,
instance, instance,
ErrorCodes.SETUP_FUNCTION, ErrorCodes.SETUP_FUNCTION,

View File

@ -777,6 +777,44 @@ function testRender(type: string, render: typeof renderToString) {
expect(html).toBe(`<div>hello</div>`) expect(html).toBe(`<div>hello</div>`)
}) })
// #2763
test('error handling w/ async setup', async () => {
const fn = jest.fn()
const fn2 = jest.fn()
const asyncChildren = defineComponent({
async setup() {
return Promise.reject('async child error')
},
template: `<div>asyncChildren</div>`
})
const app = createApp({
name: 'App',
components: {
asyncChildren
},
template: `<div class="app"><async-children /></div>`,
errorCaptured(error) {
fn(error)
}
})
app.config.errorHandler = error => {
fn2(error)
}
const html = await renderToString(app)
expect(html).toBe(`<div class="app"><div>asyncChildren</div></div>`)
expect(fn).toHaveBeenCalledTimes(1)
expect(fn).toBeCalledWith('async child error')
expect(fn2).toHaveBeenCalledTimes(1)
expect(fn2).toBeCalledWith('async child error')
expect('Uncaught error in async setup').toHaveBeenWarned()
})
// https://github.com/vuejs/vue-next/issues/3322 // https://github.com/vuejs/vue-next/issues/3322
test('effect onInvalidate does not error', async () => { test('effect onInvalidate does not error', async () => {
const noop = () => {} const noop = () => {}

View File

@ -39,6 +39,9 @@ describe('SSR Suspense', () => {
expect(await renderToString(createApp(Comp))).toBe(`<!---->`) expect(await renderToString(createApp(Comp))).toBe(`<!---->`)
expect('Uncaught error in async setup').toHaveBeenWarned() expect('Uncaught error in async setup').toHaveBeenWarned()
expect(
'Unhandled error during execution of setup function'
).toHaveBeenWarned()
expect('missing template').toHaveBeenWarned() expect('missing template').toHaveBeenWarned()
}) })
@ -71,6 +74,9 @@ describe('SSR Suspense', () => {
`<div><div>async</div><!----></div>` `<div><div>async</div><!----></div>`
) )
expect('Uncaught error in async setup').toHaveBeenWarned() expect('Uncaught error in async setup').toHaveBeenWarned()
expect(
'Unhandled error during execution of setup function'
).toHaveBeenWarned()
expect('missing template or render function').toHaveBeenWarned() expect('missing template or render function').toHaveBeenWarned()
}) })
@ -94,6 +100,9 @@ describe('SSR Suspense', () => {
`<div><div>async</div><div><!----></div></div>` `<div><div>async</div><div><!----></div></div>`
) )
expect('Uncaught error in async setup').toHaveBeenWarned() expect('Uncaught error in async setup').toHaveBeenWarned()
expect(
'Unhandled error during execution of setup function'
).toHaveBeenWarned()
expect('missing template').toHaveBeenWarned() expect('missing template').toHaveBeenWarned()
}) })
@ -117,6 +126,9 @@ describe('SSR Suspense', () => {
`<div><!----><div><div>async</div></div></div>` `<div><!----><div><div>async</div></div></div>`
) )
expect('Uncaught error in async setup').toHaveBeenWarned() expect('Uncaught error in async setup').toHaveBeenWarned()
expect(
'Unhandled error during execution of setup function'
).toHaveBeenWarned()
expect('missing template').toHaveBeenWarned() expect('missing template').toHaveBeenWarned()
}) })
}) })