Skip to content

Commit ccb677b

Browse files
authored
Merge pull request #245 from preactjs/fix-effect-barf
Fix effect behavior when first run throws
2 parents cb6f8ca + 7e15d3c commit ccb677b

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

.changeset/modern-bulldogs-perform.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@preact/signals-core": patch
3+
---
4+
5+
Fix effect behavior when first run throws

packages/core/src/index.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,12 @@ Effect.prototype._dispose = function () {
648648

649649
function effect(compute: () => unknown): () => void {
650650
const effect = new Effect(compute);
651-
effect._callback();
651+
try {
652+
effect._callback();
653+
} catch (err) {
654+
effect._dispose();
655+
throw err;
656+
}
652657
// Return a bound function instead of a wrapper like `() => effect._dispose()`,
653658
// because bound functions seem to be just as fast and take up a lot less memory.
654659
return effect._dispose.bind(effect);

packages/core/test/signal.test.tsx

+13
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,19 @@ describe("effect()", () => {
461461
expect(spy).to.be.calledOnce;
462462
});
463463

464+
it("should not subscribe to anything if first run throws", () => {
465+
const s = signal(0);
466+
const spy = sinon.spy(() => {
467+
s.value;
468+
throw new Error("test");
469+
});
470+
expect(() => effect(spy)).to.throw("test");
471+
expect(spy).to.be.calledOnce;
472+
473+
s.value++;
474+
expect(spy).to.be.calledOnce;
475+
});
476+
464477
it("should reset the cleanup if the effect throws", () => {
465478
const a = signal(0);
466479
const spy = sinon.spy();

0 commit comments

Comments
 (0)