diff --git a/src/vanilla/store.ts b/src/vanilla/store.ts index 3684c00e65..d474f24a5f 100644 --- a/src/vanilla/store.ts +++ b/src/vanilla/store.ts @@ -199,13 +199,15 @@ const addPendingFunction = (pending: Pending, fn: () => void) => { } const flushPending = (pending: Pending) => { - let error: unknown | undefined + let error: AnyError + let hasError = false const call = (fn: () => void) => { try { fn() } catch (e) { - if (!error) { + if (!hasError) { error = e + hasError = true } } } @@ -218,7 +220,7 @@ const flushPending = (pending: Pending) => { atomStates.forEach((atomState) => atomState.m?.l.forEach(call)) functions.forEach(call) } - if (error) { + if (hasError) { throw error } } diff --git a/tests/vanilla/store.test.tsx b/tests/vanilla/store.test.tsx index 8a765240a0..9905909ea8 100644 --- a/tests/vanilla/store.test.tsx +++ b/tests/vanilla/store.test.tsx @@ -876,3 +876,23 @@ describe('should mount and trigger listeners even when an error is thrown', () = expect(listener).toHaveBeenCalledOnce() }) }) + +it('throws falsy errors in onMount, onUnmount, and listeners', () => { + const store = createStore() + const a = atom(0) + a.onMount = () => { + throw '' + } + expect(() => store.sub(a, () => {})).toThrow('') + const b = atom(0) + b.onMount = () => () => { + throw '' + } + const unsub = store.sub(b, () => {}) + expect(() => unsub()).toThrow('') + const c = atom(0) + store.sub(c, () => { + throw '' + }) + expect(() => store.set(c, 1)).toThrow('') +})