bitwarden_sync/handler.rs
1//! Event system for sync operations
2//!
3//! This module provides a trait-based event system that allows other crates
4//! to respond to sync operations by implementing the [`SyncHandler`] trait
5//! and to handle sync errors via the [`SyncErrorHandler`] trait.
6
7use bitwarden_api_api::models::SyncResponseModel;
8
9use crate::SyncError;
10
11/// Type alias for sync handler error results
12pub type SyncHandlerError = Box<dyn std::error::Error + Send + Sync>;
13
14/// Trait for handling sync events
15///
16/// Implementors can register themselves with a SyncClient to receive notifications
17/// about sync operations. All handlers are called sequentially in registration order.
18///
19/// The sync lifecycle has two phases:
20/// 1. [`on_sync`](SyncHandler::on_sync) — called with the raw API response for data processing
21/// 2. [`on_sync_complete`](SyncHandler::on_sync_complete) — called after all handlers have finished
22/// `on_sync`, for post-processing work
23///
24/// If any handler returns an error, subsequent handlers are not called and the
25/// error is propagated to the caller.
26#[async_trait::async_trait]
27pub trait SyncHandler: Send + Sync {
28 /// Called after a successful sync operation
29 ///
30 /// The sync response contains raw API models from the server. Handlers are responsible
31 /// for converting these to domain types as needed and persisting data to local storage.
32 async fn on_sync(&self, response: &SyncResponseModel) -> Result<(), SyncHandlerError>;
33
34 /// Called after all handlers have finished processing [`on_sync`](SyncHandler::on_sync)
35 ///
36 /// Override this method to perform post-processing work that should happen after all
37 /// handlers have persisted their data. The default implementation is a no-op.
38 async fn on_sync_complete(&self) {}
39}
40
41/// Trait for handling errors that occur during sync operations
42///
43/// Error handlers are called when the sync operation fails, either due to
44/// an API error or a sync handler error.
45///
46/// Error handlers are called sequentially in registration order while the
47/// sync lock is still held. Implementations should avoid long-running operations
48/// and must not call [`SyncClient::sync`](crate::SyncClient::sync) (which would deadlock).
49#[async_trait::async_trait]
50pub trait SyncErrorHandler: Send + Sync {
51 /// Called when a sync operation encounters an error
52 ///
53 /// The `error` parameter contains the [`SyncError`] that caused
54 /// the sync to fail. This could be an API error or a handler processing error.
55 async fn on_error(&self, error: &SyncError);
56}