Skip to content

Commit

Permalink
Make sure unrelated autoruns are still fired in cases of exception
Browse files Browse the repository at this point in the history
  • Loading branch information
mweststrate committed Dec 31, 2016
1 parent 32af513 commit 7f8291f
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 2 deletions.
17 changes: 15 additions & 2 deletions src/core/reaction.ts
Expand Up @@ -184,8 +184,21 @@ function runReactionsHelper() {
+ ` Probably there is a cycle in the reactive function: ${allReactions[0]}`);
}
let remainingReactions = allReactions.splice(0);
for (let i = 0, l = remainingReactions.length; i < l; i++)
remainingReactions[i].runReaction();
for (let i = 0, l = remainingReactions.length; i < l; i++) {
let hasError = true;
try {
remainingReactions[i].runReaction();
hasError = false;
} finally {
if (hasError) {
// Save all not-yet-run reactions
globalState.pendingReactions.push(...remainingReactions.slice(i + 1));
// This fancy recursive construction makes sure all other reactions that still can be run are run,
// before throwing the current exception (without losing the stack)
runReactionsHelper();
}
}
}
}
globalState.isRunningReactions = false;
}
Expand Down
28 changes: 28 additions & 0 deletions test/errorhandling.js
Expand Up @@ -128,6 +128,34 @@ test('exception in autorun can be recovered from', t => {
t.end()
})

test('multiple autoruns with exceptions are handled correctly', t => {
var a = mobx.observable(1)
var values = []
var d1 = mobx.autorun(() => values.push("a" + a.get()))
var d2 = mobx.autorun(() => {
if (a.get() === 2)
throw /Uhoh/
values.push("b" + a.get())
})
var d3 = mobx.autorun(() => values.push("c" + a.get()))

t.deepEqual(values, ["a1", "b1", "c1"])
values.splice(0)

t.throws(() => a.set(2), /Uhoh/)
checkGlobalState(t)

t.deepEqual(values.sort(), ["a2", "c2"]) // order is irrelevant
values.splice(0)

a.set(3)
t.deepEqual(values.sort(), ["a3", "b3", "c3"]) // order is irrelevant

checkGlobalState(t)
d1(); d2(); d3()
t.end()
})

test('deny state changes in views', function(t) {
var x = observable(3);
var z = observable(5);
Expand Down

0 comments on commit 7f8291f

Please sign in to comment.