query-db-collection: a later refetch failure of one on-demand subset never reaches that subset's live query
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
- 48/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- typescript
- Área
- database
Línea de trabajo
Start with the supplied Vitest reproduction and trace how query-db-collection records refetch failures around query.ts:3265-3280. Then follow how loadSubset:error reaches lastSubsetError in collection-subscriber.ts:108-116, and inspect the related work in #1764. Done when the owning live query exposes a failed refresh, retains its rows, and other subsets remain unaffected.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
- I've validated the bug against the latest version of DB packages
Describe the bug
With syncMode: "on-demand", once a subset has loaded, a later refetch of that subset that fails (e.g. after queryClient.invalidateQueries) is recorded only collection-wide (collection.utils.lastError). The live query that owns the subset stays ready, its utils.lastSubsetError stays undefined, and nothing tells it the data on screen could not be refreshed.
#1764 (fixed by #1756 / #1797) scoped failures of a subset's first load to the requesting subscription. This is the same expectation for a later load of a subset that already succeeded once.
Tested with @tanstack/db 0.15.2, @tanstack/query-db-collection 1.4.8, @tanstack/query-core 5.104.5 (no related commits on main since 0.15.2).
To Reproduce
Drop-in vitest test (no framework adapter):
import { expect, test } from "vitest";
import { createCollection, createLiveQueryCollection, eq } from "@tanstack/db";
import { QueryClient } from "@tanstack/query-core";
import { parseLoadSubsetOptions, queryCollectionOptions } from "@tanstack/query-db-collection";
const tick = () => new Promise((resolve) => setTimeout(resolve, 0));
const settle = async () => {
for (let i = 0; i < 30; i++) await tick();
};
test("a later refetch failure is visible on the failed subset's live query, not just collection-wide", async () => {
const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false, gcTime: 60_000 } } });
let failing = null;
const reads = [];
const collection = createCollection(queryCollectionOptions({
id: "gap-1",
queryClient,
queryKey: ["gap-1"],
syncMode: "on-demand",
getKey: (row) => row.key,
queryFn: (ctx) => {
const { filters } = parseLoadSubsetOptions(ctx.meta?.loadSubsetOptions);
const seq = filters.find((filter) => filter.field.join(".") === "seq")?.value;
reads.push(seq);
if (seq === failing) return Promise.reject(new Error("read failed"));
return Promise.resolve([{ key: seq + "-1", seq }, { key: seq + "-2", seq }]);
},
}));
const live = (seq) => createLiveQueryCollection((q) => q.from({ r: collection }).where(({ r }) => eq(r.seq, seq)));
const a = live("a");
const b = live("b");
await Promise.all([a.preload(), b.preload()]);
expect(a.toArray.map((row) => row.seq)).toEqual(["a", "a"]);
failing = "a";
await queryClient.invalidateQueries({ queryKey: ["gap-1"] });
await settle();
expect(reads.filter((seq) => seq === "a")).toHaveLength(2);
expect(a.toArray.map((row) => row.seq)).toEqual(["a", "a"]);
expect(collection.utils.lastError).toBeInstanceOf(Error);
expect(a.status === "error" || a.utils.lastSubsetError instanceof Error).toBe(true);
expect(b.status).toBe("ready");
expect(b.utils.lastSubsetError).toBeUndefined();
});
Result: the last two a assertions fail; collection.utils.lastError is set.
Expected behavior
The failed subset's live query exposes the refetch failure (error status, or at least utils.lastSubsetError), while its rows stay (a failed refresh should not empty the view) and other subsets' live queries are unaffected.
Additional context
- The error is recorded collection-wide at
query-db-collection/src/query.ts:3265-3266, and marks the collection only while it is loading (:3278-3280).lastSubsetErroris fed only byloadSubset:error(db/src/query/live/collection-subscriber.ts:108-116), which an observer refetch failure never emits. - Related: #672 (first-class error tracking), #1764.
- Why it matters: an app showing paged server data (ratings, history) cannot tell a member "couldn't refresh, retry" for one view. We currently read the query cache directly to find a failed subset's error.
- Happy to send a PR (with the oracle coverage CONTRIBUTING asks for) if you'd like to assign it; equally fine if you'd rather fix it in your own flow. The test above is free to adopt as-is.
The repro was written with an AI coding assistant and checked by hand against the installed sources.
- Lenguaje dominante
- TypeScript
- Estrellas
- 4k
- Forks
- 277
- Merge medio
- 1 d 7 h
- PR fusionados (30 d)
- 170
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 TanStack/db
-
`Collection.currentStateAsChanges` JSDoc examples don’t match `CurrentStateAsChangesOptions`Abierto
Dificultad 1/5 1-3 horas Aptitud para principiantes 88/100
Los mantenedores suelen responder en 1 día
-
OfflineExecutor.dispose() never settles pendingTransactionPromisesQuizá libre de nuevo @Claire-ovo la tomó hace 8 días y no hay ningún pull request abierto. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
TanStack/db#2254 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 1 día
-
Two @tanstack/db tests time out under CPU load because a cold module import counts against the 5 s default timeoutPosiblemente ocupada @jp-knj la tomó hace 6 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
Los mantenedores suelen responder en 1 día
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 12/100
TanStack/db#2342 · 1 comentario ·
Los mantenedores suelen responder en 1 día
Todos los issues de TanStack/db
Issues similares
-
mobile-app
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
Open-Locker/Open-Locker#352 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
leanprover-community/lean4game#589 ·
Los mantenedores suelen responder en 2 días
-
Add: CS Action BGAbiertocheck:passed streams:add
Dificultad 1/5 Menos de una hora Aptitud para principiantes 68/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 82/100
unocss/unocss#5421 · 1 comentario ·
Los mantenedores suelen responder en 1 día