A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://www.mongodb.com/docs/atlas/device-sdks/sdk/kotlin/sync/handle-sync-errors/ below:

Handle Sync Errors - Kotlin SDK - Atlas Device SDKs

While developing an application that uses Device Sync, you should set an error handler. This error handler will detect and respond to any failed sync-related API calls.

Tip

For a list of common Device Sync errors and how to handle them, refer to Sync Errors in the App Services Device Sync documentation.

Set an error handler through the SyncConfiguration.errorHandler property when creating a synced realm. When an error occurs, the Kotlin SDK calls the error handler with the error object and the SyncSession that the error occurred on.

If you do not specify an error handler, the default behavior is to print the sync error to the console.

val syncErrorHandler = SyncSession.ErrorHandler { session, error ->    Log.e("Error message" + error.message.toString())}runBlocking {    val user = app.login(credentials)    val config = SyncConfiguration.Builder(user, setOf(Toad::class))        .initialSubscriptions { realm ->            add(realm.query<Toad>(), "subscription name")        }        .errorHandler(syncErrorHandler)         .build()    }

For information about setting a client log level or customizing the logger, refer to Set the Client Log Level - Kotlin SDK.

A SyncException is a subclass of AppException. A SyncException occurs when Device Sync fails.

For more information on app exceptions, refer to Handle App Errors.

An UnrecoverableSyncException occurs when Device Sync fails catastrophically. This usually means a bug in the client or connected App.

When an unrecoverable sync error occurs, you should surface the problem to the end user. Let them know that Device Sync won't work until the problem is solved. It's best to send yourself an alert so you can check the backend App logs and fix the problem as soon as possible.

A WrongSyncTypeException occurs when the client and App use different sync protocols.

The SDK supports two kinds of sync: flexible sync and partition based sync. When a client connects to an App using a sync type that does not match the App's sync type, a wrong sync type error occurs.

To recover from a wrong sync type error, update the client to use a sync type that matches the backend. This will most likely require the user to update to a new version of your app containing the fix.

A BadFlexibleSyncQueryException occurs when you try to subscribe to a flexible sync query that is not supported by the App backend. This can happen when you:

To recover from a bad flexible sync query error, update your client to use a sync query compatible with your App configuration. This will most likely require the user to update to a new version of your app containing the fix.

When using Device Sync, a client reset is an error recovery task that your client app must perform when the Device Sync server can no longer sync with the client realm. In this case, the client must reset its realm to a state that matches the server in order to restore the ability to sync.

When this occurs, the unsyncable realm on the client may contain data that has not yet synced to the server. Realm SDKs can attempt to recover or discard that data during the client reset process.

For more information about what can cause a client reset to occur, go to Client Resets in the App Services documentation.

The Realm SDKs provide client reset strategies that automatically handle most client reset errors as well as a manual recovery strategy.

Automatic reset strategies restore your local realm file to a syncable state without closing the realm or missing notifications. The differences are based on how they handle changes on the device that have not yet synced to the backend. The following strategies implement the AutomaticClientResetStrategy interface and support automatic client resets:

If your app requires specific client reset logic that can't be handled automatically, you may want or need to add a manual client reset handler using the ManuallyRecoverUnsyncedChangesStrategy interface:

Client Recovery is a feature that is enabled by default when you configure Device Sync.

To use Client Recovery, configure your realm with the recover unsynced changes or recover or discard unsynced changes strategy, and Realm automatically manages the client reset process in most cases:

Client Recovery Rules

When Client Recovery is enabled, these rules determine how objects are integrated, including how conflicts are resolved when both the backend and the client make changes to the same object:

You can specify a client reset strategy in your SyncConfiguration.syncClientResetStrategy property when configuring a synced realm.

val config = SyncConfiguration.Builder(user, setOf(Toad::class))    .initialSubscriptions { realm ->        add(realm.query<Toad>(), "subscription name")    }    .syncClientResetStrategy(clientResetStrategy)     .build()

The following sections describe how to use these client reset strategies.

The recover or discard unsynced changes strategy attempts to recover all unsynced local changes automatically during a client reset. To recover unsynced changes, Client Recovery must be enabled in your App Services App (it is enabled by default).

If the automatic recovery process fails, it falls back to a discard unsynced changes strategy. If that process process fails, it falls back again to a manual reset strategy.

This strategy provides the most robust recovery process. It is the default client reset behavior if you do not specify a client reset strategy.

Important

Do not use the recover or discard unsynced changes strategy if your application cannot lose any local data that has not yet synced to the backend.

To customize usage of recover or discard unsynced changes strategy, define a class implementing the RecoverOrDiscardUnsyncedChangesStrategy interface.

The interface provides the following callback methods:

The following example shows the RecoverOrDiscardUnsyncedChangesStrategy and each of its callbacks:

val clientResetStrategy = object : RecoverOrDiscardUnsyncedChangesStrategy {    override fun onBeforeReset(realm: TypedRealm) {        Log.i("Client reset: attempting to automatically recover unsynced changes")    }            override fun onAfterRecovery(before: TypedRealm, after: MutableRealm) {        Log.i("Client reset: successfully recovered all unsynced changes")    }        override fun onAfterDiscard(before: TypedRealm, after: MutableRealm) {        Log.i("Client reset: recovery unsuccessful, attempting to manually recover any changes")                manuallyRecoverUnsyncedData(before, after)    }            override fun onManualResetFallback( session: SyncSession, exception: ClientResetRequiredException ) {        Log.i("Client reset: manual reset required")            }    }

The recover unsynced changes strategy attempts to recover all unsynced local changes automatically during a client reset. To recover unsynced changes, Client Recovery must be enabled in your App Services App (it is enabled by default).

However, unlike the recover and discard unsynced changes strategy, it does not fall back to discard local changes if the automatic recovery fails. Instead, it falls back to manually recover changes. You might choose this client reset strategy if your app cannot lose unsynced data.

To use the recover unsynced changes strategy, define a handler implementing the RecoverUnsyncedChangesStrategy interface.

The interface provides the following callback methods:

The following example shows the RecoverUnsyncedChangesStrategy and each of its callbacks:

val clientResetStrategy = object : RecoverUnsyncedChangesStrategy {    override fun onBeforeReset(realm: TypedRealm) {        Log.i("Client reset: attempting to automatically recover unsynced changes")    }            override fun onAfterReset(before: TypedRealm, after: MutableRealm) {        Log.i("Client reset: successfully recovered all unsynced changes")    }            override fun onManualResetFallback( session: SyncSession, exception: ClientResetRequiredException ) {        Log.i("Client reset: manual reset required")            }    }

The discard unsynced changes strategy permanently deletes all local unsynced changes made since the last successful sync. This strategy restores your local realm file to a syncable state without closing the realm and while keeping notifications fully working. If this process fails, it falls back to a manual reset strategy.

This is the recommended strategy to handle any manual data recovery.

You might choose this strategy when your app requires client recovery logic that is not consistent with the Device Sync Client Recovery Rules or when you don't want to recover unsynced data.

Important

Do not use the discard unsynced changes strategy if your application cannot lose any local data that has not yet synced to the backend.

To use the discard unsynced changes strategy, define a handler implementing the DiscardUnsyncedChangesStrategy interface.

The interface provides the following callback methods:

The following example shows the DiscardUnsyncedChangesStrategy and each of its callbacks:

val clientResetStrategy = object : DiscardUnsyncedChangesStrategy {    override fun onBeforeReset(realm: TypedRealm) {        Log.i("Client reset: attempting to discard any unsynced changes")    }            override fun onAfterReset(before: TypedRealm, after: MutableRealm) {        Log.i("Client reset: attempting to manually recover any unsynced changes")                manuallyRecoverUnsyncedData(before, after)    }            override fun onManualResetFallback( session: SyncSession, exception: ClientResetRequiredException ) {        Log.i("Client reset: manual reset required")            }        override fun onError( session: SyncSession, exception: ClientResetRequiredException ) {            }    }

If the client reset cannot complete automatically, such as when there are breaking schema changes, the client reset process falls through to a manual error handler.

This may occur in any of the automatic client reset strategies:

You must provide a manual client reset implementation in the onManualResetFallback callback of the client reset handler for these strategies.

The manual reset fallback discards the local changes and allows you to create backup of the local realm using the ClientResetRequiredException.executeClientReset method.

override fun onManualResetFallback( session: SyncSession, exception: ClientResetRequiredException) {    Log.i("Client reset: manual reset required")        closeAllRealmInstances();        exception.executeClientReset();        handleBackup(recoveryFilePath);        }

Use the manually recover unsynced changes strategy for the infrequent cases where you need to customize your data recovery process. We recommend using the Discard unsynced changes strategy when possible to handle manual data recovery. You should only choose the manually recover unsynced changes strategy if the automatic recovery logic is not suitable for your app and you can't discard unsynced local data.

To use the manual recovery strategy, define your own client reset handler using the ManuallyRecoverUnsyncedChangesStrategy interface.

Before you use this method, you must close all instances of the realm that you are resetting. Any writes to the realm file made after the manual recovery callback and before the client reset being executed will not be synced. We also recommend that you create a backup of the file and report the exception.

Initiate a client reset using ClientResetRequiredException.executeClientReset().

If the client reset isn't executed manually, it will be automatically executed the next time all realm instances have been closed and re-opened (typically when the app is restarted).

You can manually test your application's client reset handling by terminating and re-enabling Device Sync.

When you terminate and re-enable Sync, clients that have previously connected with Sync are unable to connect until after they perform a client reset. Terminating Sync deletes the metadata from the server that allows the client to synchronize. The client must download a new copy of the realm from the server. The server sends a client reset error to these clients. So, when you terminate Sync, you trigger the client reset condition.

To test client reset handling:

  1. Write data from a client application and wait for it to synchronize.

  2. Terminate and re-enable Device Sync.

  3. Run the client app again. The app should get a client reset error when it tries to connect to the server.

Warning

While you iterate on client reset handling in your client application, you may need to terminate and re-enable Sync repeatedly. Terminating and re-enabling Sync renders all existing clients unable to sync until after completing a client reset. To avoid this in production, test client reset handling in a development environment.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4