Describe the bug
When an action() is given an async generator (async function*) and an uncaught error occurs inside it, the returned promise never settles and the whole JS thread freezes in an infinite microtask loop (frozen tab in the browser, hung process in Node). The same code written as a sync function* rejects correctly.
Since the transition's iterator is never removed from _actions, the transition also never completes.
Reproduction
import { action } from "@solidjs/signals";
const act = action(async function* () {
throw new Error("boom"); // any uncaught throw: failed fetch, TypeError, etc.
});
act(); // never settles; event loop is starved — a setTimeout after this never fires
Real-world shape:
const save = action(async function* (text: string) {
const res = await fetch("/api/todos", { method: "POST", body: text });
if (!res.ok) throw new Error("save failed"); // ← freezes the tab
return yield res.json();
});
Describe the bug
When an
action()is given an async generator (async function*) and an uncaught error occurs inside it, the returned promise never settles and the whole JS thread freezes in an infinite microtask loop (frozen tab in the browser, hung process in Node). The same code written as a syncfunction*rejects correctly.Since the transition's iterator is never removed from
_actions, the transition also never completes.Reproduction
Real-world shape: