]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(ssr): reset current instance if setting up options component errors (#7743)
authorSimon Johansson <simon@forintens.se>
Fri, 19 May 2023 01:09:21 +0000 (03:09 +0200)
committerGitHub <noreply@github.com>
Fri, 19 May 2023 01:09:21 +0000 (09:09 +0800)
close #7733

packages/runtime-core/src/component.ts
packages/server-renderer/__tests__/render.spec.ts

index 7048dc076856dc6a1f439063bba6cb7ceb315515..e68a8560bffec4ac5bece2d103a6d8190658bda0 100644 (file)
@@ -903,9 +903,12 @@ export function finishComponentSetup(
   if (__FEATURE_OPTIONS_API__ && !(__COMPAT__ && skipOptions)) {
     setCurrentInstance(instance)
     pauseTracking()
-    applyOptions(instance)
-    resetTracking()
-    unsetCurrentInstance()
+    try {
+      applyOptions(instance)
+    } finally {
+      resetTracking()
+      unsetCurrentInstance()
+    }
   }
 
   // warn missing template/render
index b0c3a8236fed4a2f8fe83dcb43ff9a8d0c2a78a6..0abaebf088e91aab63d9e4df81a92632932ae2ed 100644 (file)
@@ -793,6 +793,50 @@ 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: `<div>hello</div>`
+            })
+          )
+        } catch {}
+        expect(getCurrentInstance()).toBe(null)
+      })
+    })
+
+    // #7733
+    test('reset current instance after error in errorCaptured', async () => {
+      const prev = getCurrentInstance()
+
+      expect(prev).toBe(null)
+
+      const Child = {
+        created() {
+          throw new Error()
+        }
+      }
+      try {
+        await render(
+          createApp({
+            errorCaptured() {
+              throw new Error()
+            },
+            render: () => h(Child)
+          })
+        )
+      } catch {}
+      expect(
+        'Unhandled error during execution of errorCaptured hook'
+      ).toHaveBeenWarned()
+      expect(getCurrentInstance()).toBe(null)
     })
 
     test('serverPrefetch', async () => {