Skip to content

Commit adbf222

Browse files
committed
fix(debugger): fix an infinite loop issue
1 parent b4eb801 commit adbf222

File tree

3 files changed

+28
-7
lines changed

3 files changed

+28
-7
lines changed

src/reactionRunner.js

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
} from './store'
66

77
let runningReaction
8+
let isDebugging = false
89

910
export function runAsReaction (reaction, fn, context, args) {
1011
// do not build reactive relations, if the reaction is unobserved
@@ -30,9 +31,7 @@ export function runAsReaction (reaction, fn, context, args) {
3031
// register the currently running reaction to be queued again on obj.key mutations
3132
export function registerRunningReactionForOperation (operation) {
3233
if (runningReaction) {
33-
if (runningReaction.debugger) {
34-
runningReaction.debugger(operation)
35-
}
34+
debugOperation(runningReaction, operation)
3635
registerReactionForOperation(runningReaction, operation)
3736
}
3837
}
@@ -43,9 +42,7 @@ export function queueReactionsForOperation (operation) {
4342
}
4443

4544
function queueReaction (reaction) {
46-
if (reaction.debugger) {
47-
reaction.debugger(this)
48-
}
45+
debugOperation(reaction, this)
4946
// queue the reaction for later execution or run it immediately
5047
if (typeof reaction.scheduler === 'function') {
5148
reaction.scheduler(reaction)
@@ -56,6 +53,17 @@ function queueReaction (reaction) {
5653
}
5754
}
5855

56+
function debugOperation (reaction, operation) {
57+
if (reaction.debugger && !isDebugging) {
58+
try {
59+
isDebugging = true
60+
reaction.debugger(operation)
61+
} finally {
62+
isDebugging = false
63+
}
64+
}
65+
}
66+
5967
export function hasRunningReaction () {
6068
return runningReaction !== undefined
6169
}

tests/debug.test.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,4 +169,17 @@ describe('debugger', () => {
169169
}
170170
])
171171
})
172+
173+
it('should not cause infinite loops', () => {
174+
let receiverDummy
175+
const rawCounter = { num: 0 }
176+
const counter = observable(rawCounter)
177+
const debugSpy = spy(({ receiver }) => (receiverDummy = receiver.num))
178+
observe(() => counter.num, {
179+
debugger: debugSpy
180+
})
181+
182+
expect(receiverDummy).to.equal(0)
183+
expect(debugSpy.callCount).to.equal(1)
184+
})
172185
})

tests/utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export function spy (fn) {
22
function spyFn () {
3-
fn()
3+
fn.apply(this, arguments)
44
spyFn.callCount++
55
spyFn.lastArgs = Array.from(arguments)
66
spyFn.args.push(spyFn.lastArgs)

0 commit comments

Comments
 (0)