فهرست منبع

fix: ensure cleanup in watcher.get (#5988)

watcher.get should always clean up observee stack in order to prevent memory leak. Also, non-user
defined watch should rethrow error.

fix #5975
Herrington Darkholme 9 سال پیش
والد
کامیت
f6cd44c48b
2فایلهای تغییر یافته به همراه25 افزوده شده و 13 حذف شده
  1. 14 13
      src/core/observer/watcher.js
  2. 11 0
      test/unit/features/options/computed.spec.js

+ 14 - 13
src/core/observer/watcher.js

@@ -94,22 +94,23 @@ export default class Watcher {
     pushTarget(this)
     let value
     const vm = this.vm
-    if (this.user) {
-      try {
-        value = this.getter.call(vm, vm)
-      } catch (e) {
+    try {
+      value = this.getter.call(vm, vm)
+    } catch (e) {
+      if (this.user) {
         handleError(e, vm, `getter for watcher "${this.expression}"`)
+      } else {
+        throw e
       }
-    } else {
-      value = this.getter.call(vm, vm)
-    }
-    // "touch" every property so they are all tracked as
-    // dependencies for deep watching
-    if (this.deep) {
-      traverse(value)
+    } finally {
+      // "touch" every property so they are all tracked as
+      // dependencies for deep watching
+      if (this.deep) {
+        traverse(value)
+      }
+      popTarget()
+      this.cleanupDeps()
     }
-    popTarget()
-    this.cleanupDeps()
     return value
   }
 

+ 11 - 0
test/unit/features/options/computed.spec.js

@@ -193,4 +193,15 @@ describe('Options computed', () => {
     })
     expect(`computed property "a" is already defined as a prop`).toHaveBeenWarned()
   })
+
+  it('rethrow computed error', () => {
+    const vm = new Vue({
+      computed: {
+        a: () => {
+          throw new Error('rethrow')
+        }
+      }
+    })
+    expect(() => vm.a).toThrowError('rethrow')
+  })
 })