use a distinct error for out-of-sync replica

This commit is contained in:
Dustin J. Mitchell 2021-10-20 21:15:05 -04:00
parent c72cae648d
commit ec35d4fa20
4 changed files with 36 additions and 6 deletions

View file

@ -1,5 +1,5 @@
use crate::settings::Settings;
use taskchampion::{server::Server, Replica};
use taskchampion::{server::Server, Error as TCError, Replica};
use termcolor::WriteColor;
pub(crate) fn execute<W: WriteColor>(
@ -8,9 +8,32 @@ pub(crate) fn execute<W: WriteColor>(
settings: &Settings,
server: &mut Box<dyn Server>,
) -> Result<(), crate::Error> {
replica.sync(server, settings.avoid_snapshots)?;
writeln!(w, "sync complete.")?;
Ok(())
match replica.sync(server, settings.avoid_snapshots) {
Ok(()) => {
writeln!(w, "sync complete.")?;
Ok(())
}
Err(e) => match e.downcast() {
Ok(TCError::OutOfSync) => {
writeln!(w, "This replica cannot be synchronized with the server.")?;
writeln!(
w,
"It may be too old, or some other failure may have occurred."
)?;
writeln!(
w,
"To start fresh, remove the local task database and run `ta sync` again."
)?;
writeln!(
w,
"Note that doing so will lose any un-synchronized local changes."
)?;
Ok(())
}
Ok(e) => Err(e.into()),
Err(e) => Err(e.into()),
},
}
}
#[cfg(test)]

View file

@ -4,6 +4,12 @@ use thiserror::Error;
#[non_exhaustive]
/// Errors returned from taskchampion operations
pub enum Error {
/// A task-database-related error
#[error("Task Database Error: {0}")]
Database(String),
/// An error specifically indicating that the local replica cannot
/// be synchronized with the sever, due to being out of date or some
/// other irrecoverable error.
#[error("Local replica is out of sync with the server")]
OutOfSync,
}

View file

@ -140,7 +140,7 @@ impl Replica {
) -> anyhow::Result<()> {
self.taskdb
.sync(server, avoid_snapshots)
.context("Failed to synchronize")?;
.context("Failed to synchronize with server")?;
self.rebuild_working_set(false)
.context("Failed to rebuild working set after sync")?;
Ok(())

View file

@ -1,6 +1,7 @@
use super::{ops, snapshot};
use crate::server::{AddVersionResult, GetVersionResult, Server, SnapshotUrgency};
use crate::storage::{Operation, StorageTxn};
use crate::Error;
use log::{info, trace, warn};
use serde::{Deserialize, Serialize};
use std::str;
@ -97,7 +98,7 @@ pub(super) fn sync(
);
if let Some(requested) = requested_parent_version_id {
if parent_version_id == requested {
anyhow::bail!("Server's task history has diverged from this replica");
return Err(Error::OutOfSync.into());
}
}
requested_parent_version_id = Some(parent_version_id);