From 8607ec34bfb487e138eef9f4a99f3c288233380f Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Mon, 16 Apr 2018 20:23:10 +0200 Subject: [PATCH] Fixed #1480: exception in reaction effects where not handled correctly by the error handling system --- src/core/reaction.ts | 20 +++++++++++++------- test/base/errorhandling.js | 26 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/core/reaction.ts b/src/core/reaction.ts index ef3cebd62..87a44a79f 100644 --- a/src/core/reaction.ts +++ b/src/core/reaction.ts @@ -88,13 +88,17 @@ export class Reaction implements IDerivation, IReactionPublic { if (shouldCompute(this)) { this._isTrackPending = true - this.onInvalidate() - if (this._isTrackPending && isSpyEnabled()) { - // onInvalidate didn't trigger track right away.. - spyReport({ - name: this.name, - type: "scheduled-reaction" - }) + try { + this.onInvalidate() + if (this._isTrackPending && isSpyEnabled()) { + // onInvalidate didn't trigger track right away.. + spyReport({ + name: this.name, + type: "scheduled-reaction" + }) + } + } catch (e) { + this.reportExceptionInDerivation(e) } } endBatch() @@ -135,6 +139,8 @@ export class Reaction implements IDerivation, IReactionPublic { return } + if (globalState.disableErrorBoundaries) throw error + const message = `[mobx] Encountered an uncaught exception that was thrown by a reaction or observer component, in: '${this}` console.error(message, error) /** If debugging brought you here, please, read the above message :-). Tnx! */ diff --git a/test/base/errorhandling.js b/test/base/errorhandling.js index e6f4c67fb..39a1d54cb 100644 --- a/test/base/errorhandling.js +++ b/test/base/errorhandling.js @@ -708,6 +708,32 @@ test("it should be possible to handle global errors in reactions", () => { }) }) +test("it should be possible to handle global errors in reactions - 2 - #1480", () => { + utils.supressConsole(() => { + const a = mobx.observable.box(1) + const errors = [] + const d2 = mobx.onReactionError(e => errors.push(e)) + + const d = mobx.reaction( + () => a.get(), + a => { + if (a >= 2) throw a + } + ) + + a.set(2) + a.set(3) + + d2() + a.set(4) + + expect(errors).toEqual([2, 3]) + d() + + checkGlobalState() + }) +}) + test("global error handling will be skipped when using disableErrorBoundaries - 1", () => { mobx.configure({ disableErrorBoundaries: true }) try {