[2.0 / next] createOptimisticStore(fn) swallows the error when fn reads a failed async memo (createStore delivers it)
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 55/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- javascript, typescript
- Área
- frontend
Línea de trabajo
Start with the createOptimisticStore implementation and the related createStore error handling, then add the supplied reproduction under packages/signals/tests. Compare the await, memo-async, and memo-sync cases to see where the rejection is lost. Done means all six cases report ERR timeout, matching the expected output.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
A derived createOptimisticStore(fn, [], { key }) whose fn reads an async createMemo never reports that memo's rejection: readers keep the last value, with no error and no pending. The same fn under createStore delivers the error, and so does createOptimisticStore when fn awaits the promise itself.
Found at next 5e68925c (2.0.0-rc.20): a ReactiveScript app's list, after a failed reload, stayed on its old rows (or its Loading fallback) instead of showing the Errored fallback.
Repro (packages/signals/tests)
import { it } from "vitest";
import { createEffect, createMemo, createOptimisticStore, createStore, createRoot, createSignal, flush } from "../src/index.js";
const tick = async () => { for (let i = 0; i < 4; i++) { await new Promise(r => setTimeout(r, 0)); flush(); } };
for (const kind of ["optimistic", "store"]) for (const form of ["await", "memo-async", "memo-sync"])
it(`${kind} over a failing loader, ${form}`, async () => {
const asks: { key: string; res: (v: any) => void; rej: (e: any) => void }[] = [];
const ask = (key: string) => new Promise<any>((res, rej) => asks.push({ key, res, rej }));
const settle = async (key: string, f: (a: any) => void) => { for (const a of asks.filter(a => a.key === key)) { asks.splice(asks.indexOf(a), 1); f(a); } await tick(); };
const frames: string[] = []; let setFilter!: (f: string) => void;
createRoot(() => {
const [filter, sf] = createSignal("open"); setFilter = sf;
const m = createMemo(() => ask(`f:${filter()}`));
const make: any = kind === "store" ? createStore : createOptimisticStore;
const write = (d: any[], r: any) => { d.length = 0; d.push(...r.map((x: any) => ({ ...x }))); };
const [issues] = make(form === "memo-sync" ? (d: any[]) => { write(d, m()); }
: async (d: any[]) => { write(d, form === "memo-async" ? m() : await ask(`f:${filter()}`)); }, [], { key: "id" });
createEffect(() => (issues as any[]).map(i => `#${i.id}`).join(" "),
{ effect: (v: string) => { frames.push(v); }, error: (e: any) => { frames.push(`ERR ${e?.message ?? e}`); } } as any);
});
await tick();
await settle("f:open", a => a.res([{ id: 1 }, { id: 3 }]));
setFilter("closed"); flush(); await tick();
await settle("f:closed", a => a.rej(new Error("timeout")));
console.log(`${kind} ${form}: ` + frames.join(" | "));
});
Output
optimistic await: #1 #3 | ERR timeout
optimistic memo-async: #1 #3 <- error lost
optimistic memo-sync: #1 #3 <- error lost
store await: #1 #3 | ERR timeout
store memo-async: #1 #3 | ERR timeout
store memo-sync: #1 #3 | ERR timeout
Expected
ERR timeout in all six. Reading a failed memo inside the optimistic store's derive should error the store, as it does for createStore.
Related, both closed: #4271 (a keyed createProjection over a memo swallows later errors) and #4364.
- Lenguaje dominante
- TypeScript
- Estrellas
- 36.2k
- Forks
- 1.1k
- Merge medio
- 11 h 48 min
- PR fusionados (30 d)
- 441
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de solidjs/solid
-
Dificultad 3/5 1-2 días Aptitud para principiantes 52/100
Los mantenedores suelen responder en 1 día
-
Dificultad 3/5 1-2 días Aptitud para principiantes 65/100
Los mantenedores suelen responder en 1 día
-
Dificultad 3/5 1-2 días Aptitud para principiantes 58/100
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 52/100
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 4/5 3-5 días Aptitud para principiantes 48/100
Los mantenedores suelen responder en 1 día
Todos los issues de solidjs/solid
Issues similares
-
area:cli bug P4
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
Los mantenedores suelen responder en 1 día
-
bug from-studio
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
esengine/DeepSeek-Reasonix#14868 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
linxiv-dev/linXiv#384 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
scope:core type:security
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
Los mantenedores suelen responder en 1 día
-
follow-redirects updateAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 66/100
mailgun/mailgun.js#544 ·