diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts
index 51147ccc8f4..fe81efedfaf 100644
--- a/packages/runtime-core/src/component.ts
+++ b/packages/runtime-core/src/component.ts
@@ -23,7 +23,7 @@ import {
} from './componentProps'
import { Slots, initSlots, InternalSlots } from './componentSlots'
import { warn } from './warning'
-import { ErrorCodes, callWithErrorHandling } from './errorHandling'
+import { ErrorCodes, callWithAsyncErrorHandling } from './errorHandling'
import { AppContext, createAppContext, AppConfig } from './apiCreateApp'
import { Directive, validateDirectiveName } from './directives'
import {
@@ -579,7 +579,7 @@ function setupStatefulComponent(
currentInstance = instance
pauseTracking()
- const setupResult = callWithErrorHandling(
+ const setupResult = callWithAsyncErrorHandling(
setup,
instance,
ErrorCodes.SETUP_FUNCTION,
diff --git a/packages/server-renderer/__tests__/render.spec.ts b/packages/server-renderer/__tests__/render.spec.ts
index 85d537621b8..e537d9d78d5 100644
--- a/packages/server-renderer/__tests__/render.spec.ts
+++ b/packages/server-renderer/__tests__/render.spec.ts
@@ -777,6 +777,44 @@ function testRender(type: string, render: typeof renderToString) {
expect(html).toBe(`
hello
`)
})
+ // #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: `asyncChildren
`
+ })
+ const app = createApp({
+ name: 'App',
+ components: {
+ asyncChildren
+ },
+ template: ``,
+ errorCaptured(error) {
+ fn(error)
+ }
+ })
+
+ app.config.errorHandler = error => {
+ fn2(error)
+ }
+
+ const html = await renderToString(app)
+ expect(html).toBe(``)
+
+ 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
test('effect onInvalidate does not error', async () => {
const noop = () => {}
diff --git a/packages/server-renderer/__tests__/ssrSuspense.spec.ts b/packages/server-renderer/__tests__/ssrSuspense.spec.ts
index a7d10787833..3cdd8137370 100644
--- a/packages/server-renderer/__tests__/ssrSuspense.spec.ts
+++ b/packages/server-renderer/__tests__/ssrSuspense.spec.ts
@@ -39,6 +39,9 @@ describe('SSR Suspense', () => {
expect(await renderToString(createApp(Comp))).toBe(``)
expect('Uncaught error in async setup').toHaveBeenWarned()
+ expect(
+ 'Unhandled error during execution of setup function'
+ ).toHaveBeenWarned()
expect('missing template').toHaveBeenWarned()
})
@@ -71,6 +74,9 @@ describe('SSR Suspense', () => {
``
)
expect('Uncaught error in async setup').toHaveBeenWarned()
+ expect(
+ 'Unhandled error during execution of setup function'
+ ).toHaveBeenWarned()
expect('missing template or render function').toHaveBeenWarned()
})
@@ -94,6 +100,9 @@ describe('SSR Suspense', () => {
``
)
expect('Uncaught error in async setup').toHaveBeenWarned()
+ expect(
+ 'Unhandled error during execution of setup function'
+ ).toHaveBeenWarned()
expect('missing template').toHaveBeenWarned()
})
@@ -117,6 +126,9 @@ describe('SSR Suspense', () => {
``
)
expect('Uncaught error in async setup').toHaveBeenWarned()
+ expect(
+ 'Unhandled error during execution of setup function'
+ ).toHaveBeenWarned()
expect('missing template').toHaveBeenWarned()
})
})