Skip to content

Improve error recovery in sync client - #218

Open
simolus3 wants to merge 2 commits into
mainfrom
sync-client-consistent-errors
Open

Improve error recovery in sync client#218
simolus3 wants to merge 2 commits into
mainfrom
sync-client-consistent-errors

Conversation

@simolus3

@simolus3 simolus3 commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

This simplifies the control flow in the sync client to make sure we handle errors in a consistent manner. This fixes a bug I noticed while working on the Kotlin SDK: If we send say an invalid sync line, the client errors and the state is then set to ClientState::Idle. SDKs also invoke powersync_control('stop') after errors, which then does nothing as the client has already been reset. This causes SDKs to miss the hint that the sync status should be set to disconnected.

Currently, the sync client is implemented as an async future that is polled on each event. To be able to recover from some errors (namely wa-sqlite returning SQLITE_BUSY for async retries), we already have a manual state machine:

  1. We first operate on an immutable reference to sync client state and an event, returning a state machine transition or an error.
  2. If that was successful, we apply the transition (which is infallible).

At this point, we might as well call that manually instead of using the future as an indirection. So, this migrates all events to be based on that state machine (we only used it when handling sync lines before) and drops the async method.

This ensures that we consistently update the sync status when the client is reset, and makes all errors recoverable (which in many cases doesn't make sense: An invalid sync line should lead to a restart. But crucially, this lets the SDK be in control of how errors are handled). This is safe because powersync_control can only be called in transactions and because the only step capable of erroring has an immutable reference. Thus, errors are guaranteed to cause no further side-effects, everything is reset to the state before the failing call.

Apart from consistently sending a disconnect status update before stop instructions, the sync client behaves the same and eixsting tests continue to work.

AI use: Reviewed with Claude Code, which found minor issues I've fixed by hand.

@simolus3
simolus3 marked this pull request as ready for review August 20, 2026 11:12
@simolus3
simolus3 requested a review from rkistner August 20, 2026 11:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant