From dfbc27b0e4b2ee0d84f0d639faea31dd6175cd21 Mon Sep 17 00:00:00 2001 From: Herrington Darkholme <nonamesheep1@gmail.com> Date: Wed, 28 Jun 2017 14:00:29 +0800 Subject: [PATCH] fix: ensure cleanup in watcher.get watcher.get should always clean up observee stack in order to prevent memory leak. Also, non-user defined watch should rethrow error. #5975 --- src/core/observer/watcher.js | 27 +++++++++++---------- test/unit/features/options/computed.spec.js | 11 +++++++++ 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/core/observer/watcher.js b/src/core/observer/watcher.js index 3f3993df8be..40253149c34 100644 --- a/src/core/observer/watcher.js +++ b/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 } diff --git a/test/unit/features/options/computed.spec.js b/test/unit/features/options/computed.spec.js index a48c7ed13b7..7bd0b151ac4 100644 --- a/test/unit/features/options/computed.spec.js +++ b/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') + }) })