query-db-collection: a later refetch failure of one on-demand subset never reaches that subset's live query
Les mainteneurs répondent en général sous 1 jour
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Accessibilité débutants
- 48/100
- Type d'issue
- Bug
- Clarté
- Clairement spécifiée
- Activité
- Active
- Stack technique
- typescript
- Domaine
- database
Piste de recherche
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.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
- 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.
- Langage dominant
- TypeScript
- Étoiles
- 4k
- Forks
- 277
- Merge moyen
- 1 j 9 h
- PR mergées (30 j)
- 139
Préparer son environnement
- Aucun Dockerfile ni fichier Docker Compose
- Propose un modèle de pull request
- Lire le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de TanStack/db
-
`Collection.currentStateAsChanges` JSDoc examples don’t match `CurrentStateAsChangesOptions`Ouverte
Difficulté 1/5 1-3 heures Accessibilité débutants 88/100
Les mainteneurs répondent en général sous 1 jour
-
OfflineExecutor.dispose() never settles pendingTransactionPromisesPeut-être à nouveau libre @Claire-ovo l’a pris il y a 11 jours, et aucune pull request n’est ouverte. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
TanStack/db#2254 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
Les mainteneurs répondent en général sous 1 jour
-
Two @tanstack/db tests time out under CPU load because a cold module import counts against the 5 s default timeoutPeut-être pris @jp-knj l’a pris il y a 9 jours. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 82/100
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 4/5 3-5 jours Accessibilité débutants 48/100
Les mainteneurs répondent en général sous 1 jour
Toutes les issues de TanStack/db
Issues similaires
-
bug
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
Yeraze/meshmonitor#6239 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 82/100
better-auth/better-auth#12292 · 1 réaction ·
Les mainteneurs répondent en général sous 1 jour
-
The sample email preview's ResizeObserver is never disconnected and keeps raising errors after leaving SettingsPeut-être pris Une pull request liée à cette issue est ouverte ou déjà fusionnée. Ouvertebug
Difficulté 2/5 1-3 heures Accessibilité débutants 82/100
Les mainteneurs répondent en général sous 1 jour
-
area:ui bug effort:S priority:P2
Difficulté 2/5 1-3 heures Accessibilité débutants 72/100
Les mainteneurs répondent en général sous 1 jour
-
Typo in WSL project description on Projects pagePeut-être pris @akhil9tiet l’a pris aujourd’hui. Ouverte
Difficulté 1/5 Moins d'une heure Accessibilité débutants 75/100
microsoft/opensource.microsoft.com#1066 · 1 commentaire ·