Skip to content

Commit d668d48

Browse files
authored
fix(runtime-core): handle error in async setup (#2881)
1 parent abd129d commit d668d48

File tree

3 files changed

+52
-2
lines changed

3 files changed

+52
-2
lines changed

packages/runtime-core/src/component.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import {
2323
} from './componentProps'
2424
import { Slots, initSlots, InternalSlots } from './componentSlots'
2525
import { warn } from './warning'
26-
import { ErrorCodes, callWithErrorHandling } from './errorHandling'
26+
import { ErrorCodes, callWithAsyncErrorHandling } from './errorHandling'
2727
import { AppContext, createAppContext, AppConfig } from './apiCreateApp'
2828
import { Directive, validateDirectiveName } from './directives'
2929
import {
@@ -579,7 +579,7 @@ function setupStatefulComponent(
579579

580580
currentInstance = instance
581581
pauseTracking()
582-
const setupResult = callWithErrorHandling(
582+
const setupResult = callWithAsyncErrorHandling(
583583
setup,
584584
instance,
585585
ErrorCodes.SETUP_FUNCTION,

packages/server-renderer/__tests__/render.spec.ts

+38
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,44 @@ function testRender(type: string, render: typeof renderToString) {
777777
expect(html).toBe(`<div>hello</div>`)
778778
})
779779

780+
// #2763
781+
test('error handling w/ async setup', async () => {
782+
const fn = jest.fn()
783+
const fn2 = jest.fn()
784+
785+
const asyncChildren = defineComponent({
786+
async setup() {
787+
return Promise.reject('async child error')
788+
},
789+
template: `<div>asyncChildren</div>`
790+
})
791+
const app = createApp({
792+
name: 'App',
793+
components: {
794+
asyncChildren
795+
},
796+
template: `<div class="app"><async-children /></div>`,
797+
errorCaptured(error) {
798+
fn(error)
799+
}
800+
})
801+
802+
app.config.errorHandler = error => {
803+
fn2(error)
804+
}
805+
806+
const html = await renderToString(app)
807+
expect(html).toBe(`<div class="app"><div>asyncChildren</div></div>`)
808+
809+
expect(fn).toHaveBeenCalledTimes(1)
810+
expect(fn).toBeCalledWith('async child error')
811+
812+
expect(fn2).toHaveBeenCalledTimes(1)
813+
expect(fn2).toBeCalledWith('async child error')
814+
815+
expect('Uncaught error in async setup').toHaveBeenWarned()
816+
})
817+
780818
// https://github.com/vuejs/vue-next/issues/3322
781819
test('effect onInvalidate does not error', async () => {
782820
const noop = () => {}

packages/server-renderer/__tests__/ssrSuspense.spec.ts

+12
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ describe('SSR Suspense', () => {
3939

4040
expect(await renderToString(createApp(Comp))).toBe(`<!---->`)
4141
expect('Uncaught error in async setup').toHaveBeenWarned()
42+
expect(
43+
'Unhandled error during execution of setup function'
44+
).toHaveBeenWarned()
4245
expect('missing template').toHaveBeenWarned()
4346
})
4447

@@ -71,6 +74,9 @@ describe('SSR Suspense', () => {
7174
`<div><div>async</div><!----></div>`
7275
)
7376
expect('Uncaught error in async setup').toHaveBeenWarned()
77+
expect(
78+
'Unhandled error during execution of setup function'
79+
).toHaveBeenWarned()
7480
expect('missing template or render function').toHaveBeenWarned()
7581
})
7682

@@ -94,6 +100,9 @@ describe('SSR Suspense', () => {
94100
`<div><div>async</div><div><!----></div></div>`
95101
)
96102
expect('Uncaught error in async setup').toHaveBeenWarned()
103+
expect(
104+
'Unhandled error during execution of setup function'
105+
).toHaveBeenWarned()
97106
expect('missing template').toHaveBeenWarned()
98107
})
99108

@@ -117,6 +126,9 @@ describe('SSR Suspense', () => {
117126
`<div><!----><div><div>async</div></div></div>`
118127
)
119128
expect('Uncaught error in async setup').toHaveBeenWarned()
129+
expect(
130+
'Unhandled error during execution of setup function'
131+
).toHaveBeenWarned()
120132
expect('missing template').toHaveBeenWarned()
121133
})
122134
})

0 commit comments

Comments
 (0)