Просмотр исходного кода

fix(ssr): reset current instance if setting up options component errors (#7743)

close #7733
Simon Johansson 2 лет назад
Родитель
Сommit
020851e57d

+ 6 - 3
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)
+    } finally {
+      resetTracking()
+      unsetCurrentInstance()
+    }
   }
 
   // warn missing template/render

+ 44 - 0
packages/server-renderer/__tests__/render.spec.ts

@@ -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 () => {