@@ -25,30 +25,27 @@ var uid = 0
25
25
*/
26
26
27
27
function Watcher ( vm , expOrFn , cb , options ) {
28
+ // mix in options
29
+ if ( options ) {
30
+ _ . extend ( this , options )
31
+ }
28
32
var isFn = typeof expOrFn === 'function'
29
33
this . vm = vm
30
34
vm . _watchers . push ( this )
31
35
this . expression = isFn ? expOrFn . toString ( ) : expOrFn
32
36
this . cb = cb
33
37
this . id = ++ uid // uid for batching
34
38
this . active = true
35
- options = options || { }
36
- this . deep = ! ! options . deep
37
- this . user = ! ! options . user
38
- this . twoWay = ! ! options . twoWay
39
- this . sync = ! ! options . sync
40
- this . lazy = ! ! options . lazy
41
- this . dirty = this . lazy
42
- this . filters = options . filters
43
- this . preProcess = options . preProcess
39
+ this . dirty = this . lazy // for lazy watchers
44
40
this . deps = [ ]
45
41
this . newDeps = null
42
+ this . prevError = null // for async error stacks
46
43
// parse expression for getter/setter
47
44
if ( isFn ) {
48
45
this . getter = expOrFn
49
46
this . setter = undefined
50
47
} else {
51
- var res = expParser . parse ( expOrFn , options . twoWay )
48
+ var res = expParser . parse ( expOrFn , this . twoWay )
52
49
this . getter = res . get
53
50
this . setter = res . set
54
51
}
@@ -196,6 +193,11 @@ p.update = function (shallow) {
196
193
: false
197
194
: ! ! shallow
198
195
this . queued = true
196
+ // record before-push error stack in debug mode
197
+ /* istanbul ignore if */
198
+ if ( process . env . NODE_ENV !== 'production' && config . debug ) {
199
+ this . prevError = new Error ( '[vue] async stack trace' )
200
+ }
199
201
batcher . push ( this )
200
202
}
201
203
}
@@ -216,9 +218,28 @@ p.run = function () {
216
218
// non-shallow update (caused by a vm digest).
217
219
( ( _ . isArray ( value ) || this . deep ) && ! this . shallow )
218
220
) {
221
+ // set new value
219
222
var oldValue = this . value
220
223
this . value = value
221
- this . cb ( value , oldValue )
224
+ // in debug + async mode, when a watcher callbacks
225
+ // throws, we also throw the saved before-push error
226
+ // so the full cross-tick stack trace is available.
227
+ var prevError = this . prevError
228
+ /* istanbul ignore if */
229
+ if ( process . env . NODE_ENV !== 'production' &&
230
+ config . debug && prevError ) {
231
+ this . prevError = null
232
+ try {
233
+ this . cb . call ( this . vm , value , oldValue )
234
+ } catch ( e ) {
235
+ _ . nextTick ( function ( ) {
236
+ throw prevError
237
+ } , 0 )
238
+ throw e
239
+ }
240
+ } else {
241
+ this . cb . call ( this . vm , value , oldValue )
242
+ }
222
243
}
223
244
this . queued = this . shallow = false
224
245
}
0 commit comments