Real-time Collaboration: Add sync connection error handling#74075
Conversation
|
👋 Thanks for your first Pull Request and for helping build the future of Gutenberg and WordPress, @shekharnwagh! In case you missed it, we'd love to have you join us in our Slack community. If you want to learn more about WordPress development in general, check out the Core Handbook full of helpful information. |
Great work so far! My two main comments are:
Instead of a new store within export type ProviderCreator = (
objectType: ObjectType,
objectId: ObjectID | null,
ydoc: Y.Doc,
onStateChange: ( newState: ConnectionState ) => void
) => Promise< ProviderCreatorResult >;The provider is expected to call the As for subscribing to these state changes in the block editor, I thought about the following options:
I also want to make sure our approach is ready to work with multiple entities! If we have loaded a post entity, a notes collection, and a template entity for syncing, how do we communicate the connection states of all three? What triggers the modal: a single connection error or multiple errors? If multiple, how many? Should a connection state error for a one enetity disrupt the ability to continue working with others that are still connected? Mapping this out now will help light the path. |
819e8cf to
8d92d45
Compare
1f267a3 to
ec9f334
Compare
|
@chriszarate Thank you for the review and suggestions!
Moved this to being managed in core-data under the key interface SyncConnectionState {
status: 'connected' | 'disconnected';
errorType?: 'auth-failed' | 'too-many-connections' | 'connection-expired' | 'custom' | string;
title?: string; // Optinal custom title for the modal
description?: string; // Optional custom description for the modal
}
This structure maintains the connection state on a per-entity basis, making it suitable for handling multiple entities at once. At present, the modal is shown for the first entity that reports a disconnected state. This helps avoid situations where, for example, a meta field fails to sync but the user perceives the post as syncing successfully, potentially causing confusion. In most cases, issues that trigger the modal might be server connection errors, authentication failures, or sync limits which are likely unrelated to any specific entity and would affect all entities being synced. But if we can think of cases where an error might be entity specific, we can look into options on how to handle this. |
I'm thinking mostly of connection errors that only affect 1 entity because of an n + 1 problem like a connection limit. |
I'm inclined to show the modal even if a single entity encounters connection issues. This would ensure atomic behavior, where the sync either completes entirely or not at all, unless the issue is specific to a particular entity and due to sync server like auth, connection limit, etc. |
| } from '@wordpress/components'; | ||
| import { __ } from '@wordpress/i18n'; | ||
| import { error as errorIcon } from '@wordpress/icons'; | ||
| import { getConnectionStatusMessage } from '@wordpress/sync'; |
There was a problem hiding this comment.
It would be nice not to import the sync package at all and continue to rely purely on core-data.
Is there a better pattern than translating codes to user-ready text? I see from core-data/src/selectors.js that there are many examples of Error objects in state. Errors have a message property and could also provide a data property for additional context.
There was a problem hiding this comment.
I moved the sync package dependency by moving the util to editor package. I went with using plain objects instead of Error object to keep it simple (no having create an instance and then attach additional fields). What would be other upside of using Error instances ?
|
@shekharnwagh Thank you for working on this! Error results overlap with a problem I'm working on over in add/rtc-version-check, where I'd like to disconnect a user when another user joins with a newer Anyway, I'd like to understand if/how I can propagate an error when a version change is detected using your code in this branch. In my current version of the code, I call const onStateUpdate = createVersionObserver( ydoc, () => {
// Disconnect providers when outdated client is detected
unload();
} );This sort of works, but our websocket client interprets the I need some way instead of |
@alecgeatches You can call |
af3e249 to
33f31ec
Compare
9d00f34 to
7b467e1
Compare
1da843a to
e4ebef9
Compare
Adds JSDoc to OnStateChangeCallback, ProviderCreatorOptions, SyncConnectionError, SyncConnectionState, and SyncConnectionStatus.
2e0be8c to
7009246
Compare
|
The failing test in this PR Playwright - 1 has been marked as flaky and has a lot of recent failures. It doesn't seem to be related to any changes here, and test artifacts show nothing related to this PR. The test also passes locally in testing. Based on all that, I'm planning to merge this and ignore the failure. |
61eab34
into
WordPress:wpvip/rtc-plugin
…s#74075) * Add sync connection error handling Creates a provider-agnostic system for sync providers to report connection errors and display appropriate UI to users. * Consolidate sync connection state into core-data Removes the separate syncConnectionStore and moves connection state management into core-data. Sync providers now receive an onStateChange callback to report connection status for both entities and collections. * Remove sync package dependency from editor Moves sync error message handling from @wordpress/sync into editor utils. * Use event emitter pattern for provider status events Replace callback injection with event listener pattern for reporting provider connection status. Providers now expose an on() method that allows attaching listeners after creation, rather than receiving callbacks as constructor parameters. * Document sync provider connection state types Adds JSDoc to OnStateChangeCallback, ProviderCreatorOptions, SyncConnectionError, SyncConnectionState, and SyncConnectionStatus.
…74075) * Add sync connection error handling Creates a provider-agnostic system for sync providers to report connection errors and display appropriate UI to users. * Consolidate sync connection state into core-data Removes the separate syncConnectionStore and moves connection state management into core-data. Sync providers now receive an onStateChange callback to report connection status for both entities and collections. * Remove sync package dependency from editor Moves sync error message handling from @wordpress/sync into editor utils. * Use event emitter pattern for provider status events Replace callback injection with event listener pattern for reporting provider connection status. Providers now expose an on() method that allows attaching listeners after creation, rather than receiving callbacks as constructor parameters. * Document sync provider connection state types Adds JSDoc to OnStateChangeCallback, ProviderCreatorOptions, SyncConnectionError, SyncConnectionState, and SyncConnectionStatus.
…s#74075) * Add sync connection error handling Creates a provider-agnostic system for sync providers to report connection errors and display appropriate UI to users. * Consolidate sync connection state into core-data Removes the separate syncConnectionStore and moves connection state management into core-data. Sync providers now receive an onStateChange callback to report connection status for both entities and collections. * Remove sync package dependency from editor Moves sync error message handling from @wordpress/sync into editor utils. * Use event emitter pattern for provider status events Replace callback injection with event listener pattern for reporting provider connection status. Providers now expose an on() method that allows attaching listeners after creation, rather than receiving callbacks as constructor parameters. * Document sync provider connection state types Adds JSDoc to OnStateChangeCallback, ProviderCreatorOptions, SyncConnectionError, SyncConnectionState, and SyncConnectionStatus.
…74075) * Add sync connection error handling Creates a provider-agnostic system for sync providers to report connection errors and display appropriate UI to users. * Consolidate sync connection state into core-data Removes the separate syncConnectionStore and moves connection state management into core-data. Sync providers now receive an onStateChange callback to report connection status for both entities and collections. * Remove sync package dependency from editor Moves sync error message handling from @wordpress/sync into editor utils. * Use event emitter pattern for provider status events Replace callback injection with event listener pattern for reporting provider connection status. Providers now expose an on() method that allows attaching listeners after creation, rather than receiving callbacks as constructor parameters. * Document sync provider connection state types Adds JSDoc to OnStateChangeCallback, ProviderCreatorOptions, SyncConnectionError, SyncConnectionState, and SyncConnectionStatus.
…s#74075) * Add sync connection error handling Creates a provider-agnostic system for sync providers to report connection errors and display appropriate UI to users. * Consolidate sync connection state into core-data Removes the separate syncConnectionStore and moves connection state management into core-data. Sync providers now receive an onStateChange callback to report connection status for both entities and collections. * Remove sync package dependency from editor Moves sync error message handling from @wordpress/sync into editor utils. * Use event emitter pattern for provider status events Replace callback injection with event listener pattern for reporting provider connection status. Providers now expose an on() method that allows attaching listeners after creation, rather than receiving callbacks as constructor parameters. * Document sync provider connection state types Adds JSDoc to OnStateChangeCallback, ProviderCreatorOptions, SyncConnectionError, SyncConnectionState, and SyncConnectionStatus.
…s#74075) * Add sync connection error handling Creates a provider-agnostic system for sync providers to report connection errors and display appropriate UI to users. * Consolidate sync connection state into core-data Removes the separate syncConnectionStore and moves connection state management into core-data. Sync providers now receive an onStateChange callback to report connection status for both entities and collections. * Remove sync package dependency from editor Moves sync error message handling from @wordpress/sync into editor utils. * Use event emitter pattern for provider status events Replace callback injection with event listener pattern for reporting provider connection status. Providers now expose an on() method that allows attaching listeners after creation, rather than receiving callbacks as constructor parameters. * Document sync provider connection state types Adds JSDoc to OnStateChangeCallback, ProviderCreatorOptions, SyncConnectionError, SyncConnectionState, and SyncConnectionStatus.
…s#74075) * Add sync connection error handling Creates a provider-agnostic system for sync providers to report connection errors and display appropriate UI to users. * Consolidate sync connection state into core-data Removes the separate syncConnectionStore and moves connection state management into core-data. Sync providers now receive an onStateChange callback to report connection status for both entities and collections. * Remove sync package dependency from editor Moves sync error message handling from @wordpress/sync into editor utils. * Use event emitter pattern for provider status events Replace callback injection with event listener pattern for reporting provider connection status. Providers now expose an on() method that allows attaching listeners after creation, rather than receiving callbacks as constructor parameters. * Document sync provider connection state types Adds JSDoc to OnStateChangeCallback, ProviderCreatorOptions, SyncConnectionError, SyncConnectionState, and SyncConnectionStatus.
…s#74075) * Add sync connection error handling Creates a provider-agnostic system for sync providers to report connection errors and display appropriate UI to users. * Consolidate sync connection state into core-data Removes the separate syncConnectionStore and moves connection state management into core-data. Sync providers now receive an onStateChange callback to report connection status for both entities and collections. * Remove sync package dependency from editor Moves sync error message handling from @wordpress/sync into editor utils. * Use event emitter pattern for provider status events Replace callback injection with event listener pattern for reporting provider connection status. Providers now expose an on() method that allows attaching listeners after creation, rather than receiving callbacks as constructor parameters. * Document sync provider connection state types Adds JSDoc to OnStateChangeCallback, ProviderCreatorOptions, SyncConnectionError, SyncConnectionState, and SyncConnectionStatus.
…s#74075) * Add sync connection error handling Creates a provider-agnostic system for sync providers to report connection errors and display appropriate UI to users. * Consolidate sync connection state into core-data Removes the separate syncConnectionStore and moves connection state management into core-data. Sync providers now receive an onStateChange callback to report connection status for both entities and collections. * Remove sync package dependency from editor Moves sync error message handling from @wordpress/sync into editor utils. * Use event emitter pattern for provider status events Replace callback injection with event listener pattern for reporting provider connection status. Providers now expose an on() method that allows attaching listeners after creation, rather than receiving callbacks as constructor parameters. * Document sync provider connection state types Adds JSDoc to OnStateChangeCallback, ProviderCreatorOptions, SyncConnectionError, SyncConnectionState, and SyncConnectionStatus.
…s#74075) * Add sync connection error handling Creates a provider-agnostic system for sync providers to report connection errors and display appropriate UI to users. * Consolidate sync connection state into core-data Removes the separate syncConnectionStore and moves connection state management into core-data. Sync providers now receive an onStateChange callback to report connection status for both entities and collections. * Remove sync package dependency from editor Moves sync error message handling from @wordpress/sync into editor utils. * Use event emitter pattern for provider status events Replace callback injection with event listener pattern for reporting provider connection status. Providers now expose an on() method that allows attaching listeners after creation, rather than receiving callbacks as constructor parameters. * Document sync provider connection state types Adds JSDoc to OnStateChangeCallback, ProviderCreatorOptions, SyncConnectionError, SyncConnectionState, and SyncConnectionStatus.
…s#74075) * Add sync connection error handling Creates a provider-agnostic system for sync providers to report connection errors and display appropriate UI to users. * Consolidate sync connection state into core-data Removes the separate syncConnectionStore and moves connection state management into core-data. Sync providers now receive an onStateChange callback to report connection status for both entities and collections. * Remove sync package dependency from editor Moves sync error message handling from @wordpress/sync into editor utils. * Use event emitter pattern for provider status events Replace callback injection with event listener pattern for reporting provider connection status. Providers now expose an on() method that allows attaching listeners after creation, rather than receiving callbacks as constructor parameters. * Document sync provider connection state types Adds JSDoc to OnStateChangeCallback, ProviderCreatorOptions, SyncConnectionError, SyncConnectionState, and SyncConnectionStatus.
…74075) * Add sync connection error handling Creates a provider-agnostic system for sync providers to report connection errors and display appropriate UI to users. * Consolidate sync connection state into core-data Removes the separate syncConnectionStore and moves connection state management into core-data. Sync providers now receive an onStateChange callback to report connection status for both entities and collections. * Remove sync package dependency from editor Moves sync error message handling from @wordpress/sync into editor utils. * Use event emitter pattern for provider status events Replace callback injection with event listener pattern for reporting provider connection status. Providers now expose an on() method that allows attaching listeners after creation, rather than receiving callbacks as constructor parameters. * Document sync provider connection state types Adds JSDoc to OnStateChangeCallback, ProviderCreatorOptions, SyncConnectionError, SyncConnectionState, and SyncConnectionStatus.
…s#74075) * Add sync connection error handling Creates a provider-agnostic system for sync providers to report connection errors and display appropriate UI to users. * Consolidate sync connection state into core-data Removes the separate syncConnectionStore and moves connection state management into core-data. Sync providers now receive an onStateChange callback to report connection status for both entities and collections. * Remove sync package dependency from editor Moves sync error message handling from @wordpress/sync into editor utils. * Use event emitter pattern for provider status events Replace callback injection with event listener pattern for reporting provider connection status. Providers now expose an on() method that allows attaching listeners after creation, rather than receiving callbacks as constructor parameters. * Document sync provider connection state types Adds JSDoc to OnStateChangeCallback, ProviderCreatorOptions, SyncConnectionError, SyncConnectionState, and SyncConnectionStatus.
…s#74075) * Add sync connection error handling Creates a provider-agnostic system for sync providers to report connection errors and display appropriate UI to users. * Consolidate sync connection state into core-data Removes the separate syncConnectionStore and moves connection state management into core-data. Sync providers now receive an onStateChange callback to report connection status for both entities and collections. * Remove sync package dependency from editor Moves sync error message handling from @wordpress/sync into editor utils. * Use event emitter pattern for provider status events Replace callback injection with event listener pattern for reporting provider connection status. Providers now expose an on() method that allows attaching listeners after creation, rather than receiving callbacks as constructor parameters. * Document sync provider connection state types Adds JSDoc to OnStateChangeCallback, ProviderCreatorOptions, SyncConnectionError, SyncConnectionState, and SyncConnectionStatus.
…s#74075) * Add sync connection error handling Creates a provider-agnostic system for sync providers to report connection errors and display appropriate UI to users. * Consolidate sync connection state into core-data Removes the separate syncConnectionStore and moves connection state management into core-data. Sync providers now receive an onStateChange callback to report connection status for both entities and collections. * Remove sync package dependency from editor Moves sync error message handling from @wordpress/sync into editor utils. * Use event emitter pattern for provider status events Replace callback injection with event listener pattern for reporting provider connection status. Providers now expose an on() method that allows attaching listeners after creation, rather than receiving callbacks as constructor parameters. * Document sync provider connection state types Adds JSDoc to OnStateChangeCallback, ProviderCreatorOptions, SyncConnectionError, SyncConnectionState, and SyncConnectionStatus.
* Real-time collaboration: Add sync connection error handling (#74075) * Add sync connection error handling Creates a provider-agnostic system for sync providers to report connection errors and display appropriate UI to users. * Consolidate sync connection state into core-data Removes the separate syncConnectionStore and moves connection state management into core-data. Sync providers now receive an onStateChange callback to report connection status for both entities and collections. * Remove sync package dependency from editor Moves sync error message handling from @wordpress/sync into editor utils. * Use event emitter pattern for provider status events Replace callback injection with event listener pattern for reporting provider connection status. Providers now expose an on() method that allows attaching listeners after creation, rather than receiving callbacks as constructor parameters. * Document sync provider connection state types Adds JSDoc to OnStateChangeCallback, ProviderCreatorOptions, SyncConnectionError, SyncConnectionState, and SyncConnectionStatus. * Real-time collaboration: Add provider 'connecting' status (#74826) * Real-time collaboration: Update sync provider event name and modal handling (#74904) * Rename sync provider status event to prevent conflicts Renamed the event from 'status' to 'sync-connection-status' to make it unique and avoid conflicts. This ensures sync-specific connection state events are distinct from generic provider status events. * Show sync disconnection modal for all disconnect states Previously, the modal only appeared when connectionState.error existed. This meant users might be disconnected without seeing any indication if the disconnection didn't include a specific error object. * Real-time collaboration: Add connection status events to HTTP polling provider Adds event emitter to HTTP polling provider to report connection state changes. When the provider connects or disconnects, it emits sync-connection-status events that update core-data and trigger the disconnection modal for users. * Real-time collaboration: Improve sync connection modal with debounce Debounces initial modal display by 5s to prevent flicker during page load. Updates selector to return all connection statuses and makes onStatusChange callback mandatory for consistent error handling * Fix the handler issue in manager * Import BlockCanvasConver from private API * Restore return annotation * Fix useSelect comparison warning * Simplify implementation to onStatusChange * Remove getSyncErrorMessages export * Fix type * Fix serialize performance issue * Fix resolver test --------- Co-authored-by: Alec Geatches <alec.geatches@automattic.com> Co-authored-by: ingeniumed <ingeniumed@users.noreply.github.com> Co-authored-by: chriszarate <chris.zarate@automattic.com>
What?
Add sync connection error handling
Creates a provider-agnostic system for sync providers to report connection errors and display appropriate UI to users.
Why?
Sync providers currently have no standard way to communicate connection errors to users. When a sync provider disconnects or authentication fails, users are left in an unclear state with no feedback about what happened or how to save their work.
This PR provides a centralized system for any sync provider to report connection status and automatically display a modal to users when disconnections occur.
How?
This implementation is based on the modal from the VIP Real-Time Collaboration plugin:
https://github.com/Automattic/vip-real-time-collaboration/blob/trunk/src/components/post-locked-modal.tsx
core/sync-connection) in@wordpress/syncpackage that tracks connection status for all sync providersSyncConnectionModalcomponent in@wordpress/block-editorthat displays when any provider reports a disconnectionsetConnectionStatus()with standard error types (auth failed, too many connections, etc.) or custom messages