From 1c049d981aeb4e8dd0ef1471cec2cd6e33532cb2 Mon Sep 17 00:00:00 2001 From: Simon Johansson Date: Fri, 17 Feb 2023 10:01:36 +0100 Subject: [PATCH 1/2] fix(ssr): reset current instance if setting up options component errors close #7733 --- packages/runtime-core/src/component.ts | 9 ++-- .../server-renderer/__tests__/render.spec.ts | 41 +++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index 7048dc07685..51e0f6f2bcc 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -903,9 +903,12 @@ export function finishComponentSetup( if (__FEATURE_OPTIONS_API__ && !(__COMPAT__ && skipOptions)) { setCurrentInstance(instance) pauseTracking() - applyOptions(instance) - resetTracking() - unsetCurrentInstance() + try { + applyOptions(instance) + resetTracking() + } finally { + unsetCurrentInstance() + } } // warn missing template/render diff --git a/packages/server-renderer/__tests__/render.spec.ts b/packages/server-renderer/__tests__/render.spec.ts index b0c3a8236fe..0c8ced159f2 100644 --- a/packages/server-renderer/__tests__/render.spec.ts +++ b/packages/server-renderer/__tests__/render.spec.ts @@ -793,6 +793,47 @@ function testRender(type: string, render: typeof renderToString) { } catch {} expect(getCurrentInstance()).toBe(prev) }) + + // #7733 + test('reset current instance after error in data', async () => { + const prev = getCurrentInstance() + expect(prev).toBe(null) + try { + await render( + createApp({ + data() { + throw new Error() + }, + template: `
hello
` + }) + ) + } catch {} + expect(getCurrentInstance()).toBe(null) + }) + }) + + // #7733 + test('reset current instance after error in errorCaptured', async () => { + const prev = getCurrentInstance() + + expect(prev).toBe(null) + try { + await render( + createApp({ + errorCaptured() { + throw new Error() + }, + template: `
hello
`, + created() { + throw new Error() + } + }) + ) + } catch {} + expect( + 'Unhandled error during execution of created hook' + ).toHaveBeenWarned() + expect(getCurrentInstance()).toBe(null) }) test('serverPrefetch', async () => { From b84e544bb23918081b55b5f8785a6aa45270103c Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 19 May 2023 09:06:41 +0800 Subject: [PATCH 2/2] refactor: tweaks --- packages/runtime-core/src/component.ts | 2 +- packages/server-renderer/__tests__/render.spec.ts | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index 51e0f6f2bcc..e68a8560bff 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -905,8 +905,8 @@ export function finishComponentSetup( pauseTracking() try { applyOptions(instance) - resetTracking() } finally { + resetTracking() unsetCurrentInstance() } } diff --git a/packages/server-renderer/__tests__/render.spec.ts b/packages/server-renderer/__tests__/render.spec.ts index 0c8ced159f2..0abaebf088e 100644 --- a/packages/server-renderer/__tests__/render.spec.ts +++ b/packages/server-renderer/__tests__/render.spec.ts @@ -817,21 +817,24 @@ function testRender(type: string, render: typeof renderToString) { const prev = getCurrentInstance() expect(prev).toBe(null) + + const Child = { + created() { + throw new Error() + } + } try { await render( createApp({ errorCaptured() { throw new Error() }, - template: `
hello
`, - created() { - throw new Error() - } + render: () => h(Child) }) ) } catch {} expect( - 'Unhandled error during execution of created hook' + 'Unhandled error during execution of errorCaptured hook' ).toHaveBeenWarned() expect(getCurrentInstance()).toBe(null) })