diff --git a/CHANGELOG.md b/CHANGELOG.md index 26942f6..adf1b4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ +# 5.5.7 + +* Another fix for invalid `actionAsync` context through [#246](https://github.com/mobxjs/mobx-utils/pull/246) by [xaviergonz](https://github.com/xaviergonz) + # 5.5.6 -* Another fix for invalid `actionAsync` context when promises resolve at the same time in different actionAsync calls, by [xaviergonz](https://github.com/xaviergonz) through [#244](https://github.com/mobxjs/mobx-utils/pull/244) +* Another fix for invalid `actionAsync` context when promises resolve at the same time in different actionAsync calls through [#244](https://github.com/mobxjs/mobx-utils/pull/244) by [xaviergonz](https://github.com/xaviergonz) # 5.5.5 diff --git a/src/action-async.ts b/src/action-async.ts index dbfb988..b9c6083 100644 --- a/src/action-async.ts +++ b/src/action-async.ts @@ -74,6 +74,10 @@ export async function task(value: R | PromiseLike): Promise { await inOrderExecution() return ret + } catch (err) { + await inOrderExecution() + + throw err } finally { // only restart if it not a dangling promise (the action is not yet finished) if (unfinishedIds.has(runId)) { diff --git a/test/action-async.ts b/test/action-async.ts index 1b1dd6e..4041475 100644 --- a/test/action-async.ts +++ b/test/action-async.ts @@ -578,3 +578,45 @@ test("reusing promises", async () => { expect(values).toEqual([1, 2, 3]) expectNoActionsRunning() }) + +test("actions that throw in parallel", async () => { + mobx.configure({ enforceActions: "observed" }) + + const r = shouldThrow => + new Promise((resolve, reject) => { + setTimeout(() => { + if (shouldThrow) { + reject("Error") + return + } + resolve(42) + }, 10) + }) + + const actionAsync1 = actionAsync("actionAsync1", async () => { + try { + return await task(r(true)) + } catch (err) { + return "error" + } + }) + + const actionAsync2 = actionAsync("actionAsync2", async () => { + try { + return await task(r(false)) + } catch (err) { + return "error" + } + }) + + const result = await Promise.all([actionAsync1(), actionAsync2(), actionAsync1()]) + + expectNoActionsRunning() + expect(result).toMatchInlineSnapshot(` + Array [ + "error", + 42, + "error", + ] + `) +})