Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /
Sync Data

Gestión de errores de sincronización - Node.js SDK

Cuando usas Atlas Device Sync en tu aplicación Realm, puedes encontrar una nueva clase de errores: errores de sincronización

The Realm Node.js SDK can help you detect and handle sync errors. For example, you can write your own sync error handler to respond to specific errors. You can also define how your client app handles client resets.

You should set an error handler for apps that use Atlas Device Sync. A generic error handler will detect and respond to failed sync-related API calls to your Atlas backend.

Establezca un controlador de errores registrando una función de devolución de llamada de error como parte de SyncConfiguration.

const handleSyncError = async (session, error) => {
// ... handle the error using session and error information.
console.log(session);
console.log(error);
};
const config = {
schema: [DogSchema],
sync: {
flexible: true,
user: app.currentUser,
onError: handleSyncError,
},
};
// Open realm with config that contains error handler.
const realm = await Realm.open(config);
const handleSyncError = (
session: Realm.App.Sync.Session,
error: Realm.SyncError | Realm.ClientResetError
) => {
// ... handle the error using session and error information.
console.log(session);
console.log(error);
};
const config: Realm.Configuration = {
schema: [DogSchema],
sync: {
flexible: true,
user: app.currentUser!,
onError: handleSyncError,
},
};
// Open realm with config that contains error handler.
const realm = await Realm.open(config);

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.

You may want your sync error handler to specifically address compensating write errors in a way that makes sense for your app. The CompensatingWriteError class can help you identify and react to compensating write errors in your custom error handler.

const errorCallback = (session, error) => {
// Check if error type matches CompensatingWriteError.
if (error instanceof CompensatingWriteError) {
// Handle the compensating write error as needed.
console.debug({
name: error.name,
code: error.code,
message: error.message,
atlasLogUrl: error.logUrl,
});
const compensatingWrites = error.writes.sort((a, b) =>
a.primaryKey.toString().localeCompare(b.primaryKey.toString())
);
console.debug(compensatingWrites);
}
};
const app = new Realm.App({
id: APP_ID,
});
const credentials = Credentials.anonymous();
await app.logIn(credentials);
const realm = await Realm.open({
schema: [Person, Turtle],
sync: {
flexible: true,
user: app.currentUser,
onError: errorCallback,
},
});
const errorCallback: ErrorCallback = (session, error) => {
// Check if error type matches CompensatingWriteError.
if (error instanceof CompensatingWriteError) {
// Handle the compensating write error as needed.
console.debug({
name: error.name,
code: error.code,
message: error.message,
atlasLogUrl: error.logUrl,
});
const compensatingWrites = error.writes.sort((a, b) =>
(a.primaryKey as BSON.ObjectId)
.toString()
.localeCompare((b.primaryKey as BSON.ObjectId).toString())
);
console.debug(compensatingWrites);
}
};
const app = new Realm.App({
id: APP_ID,
});
const credentials = Credentials.anonymous();
await app.logIn(credentials);
const realm = await Realm.open({
schema: [Person, Turtle],
sync: {
flexible: true,
user: app.currentUser!,
onError: errorCallback,
},
});

A client reset error is a scenario where a client realm cannot sync data with the Atlas App Services backend. Clients in this state may continue to run and save data locally but cannot send or receive sync changesets until they perform a client reset.

Para obtener más información sobre las causas y los modos de manejo de los restablecimientos de clientes, consulte Restablecimientos de clientes de sincronización de dispositivos en la documentación de Servicios de aplicaciones.

Puede especificar qué modo de restablecimiento de cliente debe utilizar su aplicación para restaurar el realm a un estado sincronizable:

  • Modo de recuperación de cambios no sincronizados: Al seleccionar este modo, el cliente intenta recuperar los cambios no sincronizados. Elija este modo si no desea descartar los cambios no sincronizados.

  • Recover or discard unsynced changes mode: The client first attempts to recover changes that have not yet synced. If the client cannot recover unsynced data, it falls through to discard unsynced changes but continues to automatically perform the client reset. Choose this mode when you want to enable automatic client recovery to fall back to discard unsynced changes.

  • Modo descartar cambios no sincronizados: restaura el reino a un estado sincronizable descartando los cambios realizados desde la última sincronización.

  • Manual recovery mode: Downloads a new copy of the realm, and moves the unsyncable realm to a backup. Migrate unsynced data from the backup copy of the realm to the new syncable copy.

The Realm SDKs provide client reset modes that automatically handle most client reset errors.

Los modos automáticos de restablecimiento del cliente restauran tu archivo Realm local a un estado de sincronización sin cerrar el realm o perder notificaciones. Los siguientes modos de restablecimiento del cliente admiten restablecimientos automáticos del cliente:

  • Recuperar el modo de cambios no sincronizados

  • Recover or discard unsynced changes mode

  • Discard unsynced changes mode

The differences between these modes are based on how they handle changes on the device that have not yet synced to the backend. Only manual recovery mode does not perform an automatic client reset.

Choose recover unsynced changes mode to handle most client reset scenarios automatically. This attempts to recover unsynced changes when a client reset occurs.

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 to the automatic client reset mode.

New in version 10.23.0.

Client Recovery is a feature that is enabled by default when you configure Device Sync. When Client Recovery is enabled, Realm automatically manages the client reset process in most cases. The client can recover unsynced changes when there are no schema changes, or non-breaking schema changes.

To use Client Recovery, configure your realm with one of the following client reset modes:

  • Recuperar el modo de cambios no sincronizados

  • Recover or discard unsynced changes

Cuando la Recuperación de Cliente está habilitada, estas reglas determinan cómo se integran los objetos, incluyendo la resolución de conflictos cuando tanto el backend como el cliente realizan cambios en el mismo objeto:

  • Objects created locally that were not synced before client reset are synced.

  • Si se elimina un objeto en el servidor, pero se modifica en el cliente en recuperación, la eliminación tiene prioridad y el cliente descarta la actualización.

  • If an object is deleted on the recovering client, but not the server, then the client applies the server's delete instruction.

  • En el caso de actualizaciones conflictivas en el mismo campo, se aplica la actualización del cliente.

Para obtener más información sobre cómo configurar la Recuperación de cliente, consulte Recuperación de cliente en la documentación de Servicios de aplicaciones.

Client Recovery cannot succeed when your app makes breaking schema changes. A breaking change is a change that you can make in your server-side schema that requires additional action to handle. In this scenario, client reset falls back to a manual error client reset fallback.

Para obtener información sobre cambios de esquema disruptivos y no disruptivos, consulte Referencia rápida sobre cambios disruptivos y no disruptivos en la documentación de App Services.

When you choose recover unsynced changes mode, the client attempts to recover unsynced changes with Client Recovery. Choose this mode when you do not want to fall through to discard unsynced changes.

Para manejar los restablecimientos del cliente con el modo de recuperación de cambios no sincronizados, pase un ClientResetConfig al clientReset Campo de su SyncConfiguration. Incluya estas propiedades ClientResetConfiguration en:

  • mode:Establecer en "recoverUnsyncedChanges".

  • onBefore: Optional. Callback function invoked before the SDK executes this mode, when the SDK receives a client reset error from the backend. Provides a copy of the realm.

  • onAfter: opcional. Función de retorno que se activa después de que el SDK ejecuta correctamente este modo. Proporciona instancias del realm antes y después del restablecimiento del cliente.

  • onFallback: Opcional. Función de devolución de llamada que el SDK invoca solo si falla la recuperación automática. Para más información, consulte la sección "Restablecimiento manual del cliente".

The following example implements recover unsynced changes mode:

const config = {
schema: [DogSchema],
sync: {
user: app.currentUser,
flexible: true,
clientReset: {
mode: "recoverUnsyncedChanges",
onBefore: (realm) => {
// This block could be used for custom recovery, reporting, debugging etc.
},
onAfter: (beforeRealm, afterRealm) => {
// This block could be used for custom recovery, reporting, debugging etc.
},
onFallback: (session, path) => {
// See below "Manual Client Reset Fallback" section for example
},
},
},
};

In recover or discard unsynced changes mode, the client first attempts to recover changes that have not yet synced. If the client cannot recover unsynced data, it falls through to discard unsynced changes but continues to automatically perform the client reset. Choose this mode when you want to enable automatic client recovery to fall back to discard unsynced changes.

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

To handle client resets with the recover or discard unsynced changes mode, pass a ClientResetConfig to the clientReset field of your SyncConfiguration. Include these properties in the ClientResetConfiguration:

  • mode:Establecer en "recoverOrDiscardUnsyncedChanges".

  • onBefore: Optional. Callback function invoked before the SDK executes this mode, when the SDK receives a client reset error from the backend. Provides a copy of the realm.

  • onAfter: opcional. Función de retorno que se activa después de que el SDK ejecuta correctamente este modo. Proporciona instancias del realm antes y después del restablecimiento del cliente.

  • onFallback: Opcional. Función de retorno que el SDK invoca solo si tanto la recuperación automática como el descarte de cambios fallan. Para obtener más información, consulte la sección Manual restablecimiento del cliente Fallback.

The following example implements recover unsynced changes mode:

const config = {
schema: [DogSchema],
sync: {
user: app.currentUser,
flexible: true,
clientReset: {
mode: "recoverOrDiscardUnsyncedChanges",
onBefore: (realm) => {
// This block could be used for custom recovery, reporting, debugging etc.
},
onAfter: (beforeRealm, afterRealm) => {
// This block could be used for custom recovery, reporting, debugging etc.
},
onFallback: (session, path) => {
// See below "Manual Client Reset Fallback" section for example
},
},
},
};

If the client reset with recovery cannot complete automatically, like when there are breaking schema changes, the client reset process falls through to a manual error handler. This may occur in either of the client reset with recovery modes, recover unsynced changes and recover or discard unsynced changes.

Debes proporcionar una implementación manual de restablecimiento del cliente en la función de retorno SyncConfiguration.onFallback(). onFallback() toma dos argumentos:

  • session:Objeto desesión que representa el estado de la sesión de sincronización del dispositivo.

  • path: String with the path to the current realm file.

El siguiente ejemplo demuestra cómo puedes manejar manualmente este caso de error descartando todos los cambios no sincronizados:

// Must define `realm` at higher scope than `config` so it's accessible
// from the `onFallback` callback
let realm;
const config = {
schema: [DogSchema],
sync: {
user: app.currentUser,
flexible: true,
clientReset: {
mode: "recoverOrDiscardUnsyncedChanges", // or "recoverUnsyncedChanges"
// can also include `onBefore` and `onAfter` callbacks
onFallback: (_session, path) => {
try {
// Prompt user to perform a client reset immediately. If they don't,
// they won't receive any data from the server until they restart the app
// and all changes they make will be discarded when the app restarts.
const didUserConfirmReset = showUserAConfirmationDialog();
if (didUserConfirmReset) {
// Close and delete old realm from device
realm.close();
Realm.deleteFile(path);
// Perform client reset
Realm.App.Sync.initiateClientReset(app, path);
// Navigate the user back to the main page or reopen the
// the Realm and reinitialize the current page
}
} catch (err) {
// Reset failed. Notify user that they'll need to
// update the app
}
},
},
},
};
realm = await Realm.open(config);

New in version 10.11.0.

Cambiado en la versión 10.23.0: El modo pasó a llamarse de "discardLocal" a "discardUnsyncedChanges". Actualmente, ambos funcionan, pero, en una versión futura, se eliminará "discardLocal". Las funciones de retorno "clientResetBefore" y "clientResetAfter" se cambiaron a "onBefore" y "onAfter", respectivamente.

El modo Descartar cambios no sincronizados borra permanentemente todos los cambios locales no sincronizados realizados desde la última sincronización exitosa. Puedes usar esta moda cuando tu aplicación requiera una lógica de recuperación de cliente que no sea coherente con Recuperación automática del cliente, o cuando no quieras recuperar datos no sincronizados.

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

To handle client resets with the discard unsynced changes mode, pass a ClientResetConfig to the clientReset field of your SyncConfiguration. Include these properties in the ClientResetConfiguration:

  • mode:Establecer en "discardUnsyncedChanges".

  • onBefore: Optional. Callback function invoked before the SDK executes this mode, when the SDK receives a client reset error from the backend. Provides a copy of the realm.

  • onAfter: opcional. Función de retorno que se activa después de que el SDK ejecuta correctamente este modo. Proporciona instancias del realm antes y después del restablecimiento del cliente.

El siguiente ejemplo implementa el modo descartar cambios no sincronizados:

const config = {
schema: [DogSchema],
sync: {
user: app.currentUser,
flexible: true,
clientReset: {
mode: "discardUnsyncedChanges",
onBefore: (realm) => {
console.log("Beginning client reset for ", realm.path);
},
onAfter: (beforeRealm, afterRealm) => {
console.log("Finished client reset for", beforeRealm.path);
console.log("New realm path", afterRealm.path);
},
},
},
};

Si tu aplicación experimenta un cambio de esquema que afecte la compatibilidad, el modo de descartar cambios no sincronizados no puede gestionar automáticamente el restablecimiento resultante del cliente. En cambio, debe proporcionar una implementación de restablecimiento del cliente en la función de retorno de SyncConfiguration error(). El siguiente ejemplo demuestra cómo se puede gestionar manualmente este caso de error descartando todos los cambios no sincronizados:

// Once you have opened your Realm, you will have to keep a reference to it.
// In the error handler, this reference is called `realm`
async function handleSyncError(session, syncError) {
if (syncError.name == "ClientReset") {
console.log(syncError);
try {
console.log("error type is ClientReset....");
const path = realm.path; // realm.path will not be accessible after realm.close()
realm.close();
Realm.App.Sync.initiateClientReset(app, path);
// Download Realm from the server.
// Ensure that the backend state is fully downloaded before proceeding,
// which is the default behavior.
realm = await Realm.open(config);
realm.close();
} catch (err) {
console.error(err);
}
} else {
// ...handle other error types
}
}
const config = {
schema: [DogSchema],
sync: {
user: app.currentUser,
flexible: true,
clientReset: {
mode: "discardUnsyncedChanges",
onBefore: (realm) => {
// NOT used with destructive schema changes
console.log("Beginning client reset for ", realm.path);
},
onAfter: (beforeRealm, afterRealm) => {
// Destructive schema changes do not hit this function.
// Instead, they go through the error handler.
console.log("Finished client reset for", beforeRealm.path);
console.log("New realm path", afterRealm.path);
},
},
onError: handleSyncError, // invoked with destructive schema changes
},
};

Nota

Descartar con Recuperación

If you'd like to attempt to recover unsynced changes, but but discard any changes that cannot be recovered, refer to the recover or discard unsynced changes mode section.

Cambiado en la versión 10.23.0: se añadió la función de retorno onManual

En el modo manual, defines tu propio handler de restablecimiento del cliente. Tal vez quieras usar un handler de restablecimiento del cliente manual si la lógica de recuperación automática no funciona para tu aplicación y no puedes descartar los datos locales no sincronizados.

Para gestionar los restablecimientos de clientes en modo manual, pase un ClientResetConfig al clientReset campo de su SyncConfiguration. Incluya estas propiedades en ClientResetConfiguration el:

  • mode:Establecer en "manual".

  • onManual: Opcional. Función de devolución de llamada que se invoca al reiniciar el cliente. Proporciona información sobre la sesión de sincronización y la ruta al dominio actual. Si no se configura el controlador de errores onManual, el error de reinicio del cliente se revierte al controlador de errores de sincronización general.

const config = {
schema: [DogSchema],
sync: {
user: app.currentUser,
flexible: true,
clientReset: {
mode: "manual",
onManual: (session, path) => {
// handle manual client reset here
},
},
},
};

To recover data from a manual client reset requires significant amounts of code, schema concessions, and custom conflict resolution logic. If you need to implement your own custom client reset logic, see the Advanced Guide to Manual Client Reset Data Recovery.

Puede probar manualmente el manejo de restablecimiento del cliente de su aplicación finalizando y volviendo a habilitar la sincronización del dispositivo.

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. Termina y vuelve a habilitar Device Sync.

  3. Ejecuta la aplicación cliente nuevamente. La aplicación debería obtener un error de restablecimiento del cliente cuando intente conectarse al servidor.

Advertencia

Mientras itera sobre la gestión del restablecimiento de clientes en su aplicación cliente, es posible que tenga que finalizar y volver a habilitar la sincronización repetidamente. Esto impide que todos los clientes existentes puedan sincronizar hasta después de completar un restablecimiento. Para evitar esto en producción, pruebe la gestión del restablecimiento de clientes en un entorno de desarrollo.

Volver

Manage a Sync Session