-
Couldn't load subscription status.
- Fork 107
Fix error propagation from sync clients to collections #671
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Errors from Electric SQL and TanStack Query weren't being propagated to collections, causing two critical issues: 1. `preload()` would hang indefinitely when sync errors occurred, blocking apps waiting for data 2. Collections would be marked as 'ready' even when they had no synced data, leading to empty results **Changes:** - **electric-db-collection**: Implement 10-second grace period before marking collection as errored, allowing Electric's built-in retry logic to recover from transitory network issues. Remove premature `markReady()` call that was marking collections ready with no data. - **query-db-collection**: Set error status immediately after TanStack Query exhausts retries (no grace period needed since Query handles retries internally). - **preload()**: Listen for `status:error` events and reject the promise, preventing indefinite hangs when sync fails. - **Collection lifecycle**: Add `markError()` method and make `events` public. Auto-handle error recovery in `markReady()` by transitioning through loading state (error → loading → ready). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
|
More templates
@tanstack/angular-db
@tanstack/db
@tanstack/db-ivm
@tanstack/electric-db-collection
@tanstack/query-db-collection
@tanstack/react-db
@tanstack/rxdb-db-collection
@tanstack/solid-db
@tanstack/svelte-db
@tanstack/trailbase-db-collection
@tanstack/vue-db
commit: |
|
Size Change: +122 B (+0.15%) Total Size: 81.7 kB
ℹ️ View Unchanged
|
|
Size Change: 0 B Total Size: 1.46 kB ℹ️ View Unchanged
|
|
|
||
| // Managers | ||
| private _events: CollectionEventsManager | ||
| public events: CollectionEventsManager |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the manager classes are intended to be a private api, but have to be public so that they can see each other, and we can introspect them from tests. This should change it to public, but maintain the underscore on the name.
The "public" face of the events api is a set of methods on the Collection class itself that forward to this manager.
| public events: CollectionEventsManager | |
| public _events: CollectionEventsManager |
| // If recovering from error, transition to loading first | ||
| if (this.status === `error`) { | ||
| this.setStatus(`loading`) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like this, markReady should only move you to a ready state not loading.
We do not have a way in live queries to handle a ready => loading
How much handling of errors and moving between states to we expect the sync implementation to do? It seems to me there are two options for a collection:
- handle error recovery with no braking of the synced state, as they do with a truncate, and so a
markReadyto go fromerror -> readymakes sense. - catastrophic "unrecoverable" error and the sync needs to be restarted. In that case a
restartSync()method that the sync handler can call that:
- calls
.cleanup(), doing a gc and moves tocleaned-up - then calls
.startSync(), which moves toloadingand finallyreadyonce the sync marks it as such.
Option 2 has some nuances arround subscriptions we would need to handle. Existing subscription would also need to be restarted, but we had not implemented that yet, it would be the truncate message from issue #634 proposing a refactor of the reconciliation process.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whats this?
…cerns Comprehensive analysis of GitHub issue #672 and samwillis' feedback on PR #671: - Document current error handling state across collection types - Analyze proposed first-class error tracking in CollectionLifecycleManager - Examine samwillis' concerns about error state transitions - Compare Graceful Recovery vs Catastrophic Restart models - Identify design questions around state transition validity - Propose solution path supporting both recovery patterns - Highlight backwards compatibility and testing considerations Key findings: - Query collections use closure-based error tracking - Electric collections lack error tracking entirely - Current transitions don't allow error → ready or error → loading - Live queries can't handle ready → loading transitions - Two distinct error recovery patterns needed for different scenarios 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Summary
Fixes critical error propagation issues where errors from Electric SQL and TanStack Query weren't being propagated to collections, causing:
preload()hanging indefinitely - When sync errors occurred, apps waiting forpreload()would block foreverstatus: 'ready'even when they had failed to sync any dataChanges
Electric-db-collection (
packages/electric-db-collection/src/electric.ts)markReady()call that was incorrectly marking collections ready before data syncedQuery-db-collection (
packages/query-db-collection/src/query.ts)preload() fix (
packages/db/src/collection/sync.ts)status:errorevents and reject the promiseCollection lifecycle improvements (
packages/db/src/collection/)markError()method for sync implementations to set error stateeventsproperty public (was_eventsprivate)markReady()now auto-handles error recovery by transitioning through loading state (error → loading → ready)errorcan transition toidleorloadingTest plan
@tanstack/electric-db-collection@tanstack/query-db-collectionpreload()rejects after 10 seconds of errors🤖 Generated with Claude Code