From d668d48e9e5211a49ee53361ea5b4d67ba16e0a3 Mon Sep 17 00:00:00 2001 From: edison Date: Fri, 26 Mar 2021 22:26:30 +0800 Subject: [PATCH] fix(runtime-core): handle error in async setup (#2881) --- packages/runtime-core/src/component.ts | 4 +- .../server-renderer/__tests__/render.spec.ts | 38 +++++++++++++++++++ .../__tests__/ssrSuspense.spec.ts | 12 ++++++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index 51147ccc..fe81efed 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 85d53762..e537d9d7 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(`
asyncChildren
`) + + 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 a7d10787..3cdd8137 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', () => { `
async
` ) 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', () => { `
async
` ) 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', () => { `
async
` ) expect('Uncaught error in async setup').toHaveBeenWarned() + expect( + 'Unhandled error during execution of setup function' + ).toHaveBeenWarned() expect('missing template').toHaveBeenWarned() }) })