Make initial sync errors final and report later failures as Collection health
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 8/100
- Tipo de issue
- Refactorización
- Claridad
- Bastante claro
- Estado de actividad
- Activo
- Stack tecnológico
- angular, react, sqlite, typescript
Línea de trabajo
Start with PLAN.md and the design folder in docs/contributing/designs/source-failure-and-health/ on the feat/source-health-channel branch, then the oracle at packages/db/tests/source-health-oracle.test.ts. Stage 1 is in packages/db, so read the health API there before touching any adapter. Done means the listed adapter and framework work lands, the oracle passes, and the breaking changeset ships. This is maintainer-led design work, not a first task.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
Make an initial sync error final, and report problems after the first ready as health metadata instead of an error status. A live query exposes an errors tree for every Collection it depends on. This is a breaking change. Stage 1 (core) is done on the branch feat/source-health-channel (e8508df79). The plan, design, and TLA+ models are in docs/contributing/designs/source-failure-and-health/ on that branch.
Decisions
The maintainer made these decisions on 2026-10-13:
- A retry that succeeds is a success. While a source retries, it reports nothing, and the Collection stays
loading. markErroris final for its sync attempt. A source calls it only when it gives up. The framework never moveserrorback toready.- Recovery is the app's job.
cleanup()thenpreload(), a refetch, or a user refresh starts a fresh attempt. - A final initial error reaches every consumer, with its cause. Readiness waits reject, and live queries enter error for every shape. Suspense throws, and Effects are disposed.
statusis only the initial gate. After the first ready, a sync failure is metadata on the Collection. The data stays, even if it grows stale.useLiveQueryreturns anerrorstree. It has one node for each Collection the query depends on. The shape is always the same, and apps can parse it.- An Effect works the same as a query. Its gate is "every initial load settled", whatever
skipInitialsays. - IndexedDB closure stays a crash. A closed local store cannot recover.
- Ordering. When both change,
status:changefires beforehealth:change, in the same tick. - The
errorstree keeps stable object identity. A node changes only when something in its subtree changes. - TrailBase does not resubscribe after its stream ends. A stream end reports a final health error. Reconnect is for the TrailBase maintainers.
Done in stage 1 (packages/db)
- Lifecycle.
error→readyis removed, andmarkReady()aftermarkError()throws. - Health API. The
reportError(error, { final })andreportHealthy()sync callbacks,Collection.health, and thehealth:changeevent.markError()after the first ready becomes a final health error, with a development warning. - Live queries. A source failure before the first ready fails the query for every shape, and the old
erroredSourceIdshealing is removed. After the first ready, health does not change status or rows. - The
errorstree. One node per query alias, recursing through nested live queries, with stable identity. Include nodes carryinstances: { total, inError }. A load that fails after the first ready is a request error, which clears when the load later succeeds or the demand is released. - Effects. Every Effect gates on its initial loads. After the gate, problems reach
onHealthChange, and the Effect is not disposed. - Readers and docs. The observer and pooled views expose
errors, andisErrorstays the gate.ARCHITECTURE.mdhas laws 16 and 17. - Oracle.
packages/db/tests/source-health-oracle.test.ts(propertysource-health.history) covers direct, join, self-join, nested, include, and pooled shapes, with request and Effect lanes. Base code fails 45 of 49 cells, and 16 mutants fail at assertions. The full@tanstack/dbsuite passes. - Bugs found. A pooled view over a failed source reported
isError: false. A secondmarkErrorbefore ready replaced the first error.
Remaining work
The plan's checklist (PLAN.md, sections 3.2 to 3.6) has the details.
- Adapters.
- Electric: change the
markErrorcalls after the first ready toreportError, and callreportHealthy()after recovery. - query-db: a successful refetch must not revive a failed initial load (
query.ts, themarkReady()call after an application). - PowerSync: replace the
markError/markReadyheal around the tracking rebuild. - TrailBase: a stream end reports a final health error.
- RxDB and persistence: report health, and handle a follower's view of the leader's upstream health.
- Electric: change the
- Framework hooks. React, Vue, Solid, Svelte, and Angular return
errors, and Suspense throws only for the initial gate. Add a health scenario to the shared conformance suite. Rebuildpackages/db/distfirst, because the framework packages read it. - Docs.
error-handling.md, which contradicts itself on recovery today.collection-options-creator.md, with the adapter rules.live-queries.md, with theerrors.hasErrorscallout.sqlite-persistence.mdandoffline-transactions.md.- The custom-adapter skill and the framework skills.
- Do not edit generated reference docs.
- Release. A breaking changeset with a migration guide, then the pull request.
Open items
- Code weight. Production code in stage 1 is about +418 net lines in
packages/db. Do a reduction pass before review. - Effect request errors clear only when a later load of the same source succeeds. They do not clear when the failed demand is released, because failures are tracked per source.
- Pooled views end for good when their source is cleaned up, so the oracle skips restart steps for them.
- Review record.
docs/contributing/oracle-reviews/progressive-source-readiness-tla/README.md, limit P6 ("disposes an Effect"), is now true only before the gate. - Oracle review. No
oracle-reviewhas run on the health oracle yet.
Related: #2115, #2117, #2118, #2139.
- Lenguaje dominante
- TypeScript
- Estrellas
- 3.9k
- Forks
- 272
- Merge medio
- 1 d 1 h
- PR fusionados (30 d)
- 235
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
-
Dificultad 3/5 Medio día Aptitud para principiantes 62/100
Los mantenedores suelen responder en 1 día
-
Dificultad 3/5 Medio día Aptitud para principiantes 58/100
Los mantenedores suelen responder en 1 día
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 5/100
TanStack/db#2139 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 25/100
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 35/100
Los mantenedores suelen responder en 1 día
Todos los issues de TanStack/db
Issues similares
-
Contrib indemnité de départ à la retraite : faire le pont avec le simulateur sur la page génériqueAbiertoP1
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
SocialGouv/code-du-travail-numerique#7561 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
kubernetes-sigs/headlamp#7950 ·
Los mantenedores suelen responder en 3 días
-
README for cliPosiblemente ocupada @Janvi-kapoor la tomó hoy. AbiertoOSCI'26
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
GauravKarakoti/SecureFlow#1308 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
Los mantenedores suelen responder en 1 día
-
documentation
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
vitest-dev/vitest#11577 ·
Los mantenedores suelen responder en 1 día