cob/change_graph: Log Errors

In case of a signature verification failure or failure to apply an
operation, the error is swallowed, but not logged.

During debugging, it can be crucial to understand whether these errors
occur, so log them.

If trace logging is enabled, also log the tips that are used. This
gives a better overview where operations originate from.
This commit is contained in:
Lorenz Leutgeb 2026-03-30 18:16:03 +02:00 committed by Fintan Halpenny
parent 9ff0e8b01f
commit a65ac048cb
2 changed files with 18 additions and 7 deletions

View File

@ -39,12 +39,18 @@ impl ChangeGraph {
where where
S: change::Storage<ObjectId = Oid, Parent = Oid, Signatures = ExtendedSignature>, S: change::Storage<ObjectId = Oid, Parent = Oid, Signatures = ExtendedSignature>,
{ {
log::debug!(target: "cob", "Loading object of type {typename} at {oid}"); let tip_refs = tip_refs.collect::<Vec<_>>();
if log::log_enabled!(log::Level::Debug) {
log::debug!(target: "cob", "Loading object of type {typename} at {oid}.");
} else if log::log_enabled!(log::Level::Trace) {
log::trace!(target: "cob", "Loading object of type {typename} at {oid} from tips {}.", tip_refs.iter().map(|r| r.to_string()).collect::<Vec<_>>().join(", "));
}
let mut graph: Dag<Oid, Entry> = Dag::new(); let mut graph: Dag<Oid, Entry> = Dag::new();
// Populate the initial set of node ids from the refs we have // Populate the initial set of node ids from the refs we have
let mut child_ids = Vec::from_iter(tip_refs.map(|r| r.target.id)); let mut child_ids = Vec::from_iter(tip_refs.into_iter().map(|r| r.target.id));
let mut edges_to_add = Vec::new(); let mut edges_to_add = Vec::new();
while let Some(child_id) = child_ids.pop() { while let Some(child_id) = child_ids.pop() {
@ -113,13 +119,12 @@ impl ChangeGraph {
|_, entry, siblings| { |_, entry, siblings| {
// Check the entry signatures are valid. // Check the entry signatures are valid.
if !entry.valid_signatures() { if !entry.valid_signatures() {
log::debug!("Signature verification failed for entry {}.", entry.id);
return ControlFlow::Break(()); return ControlFlow::Break(());
} }
// Apply the entry to the state, and if there's an error, prune that branch. // Apply the entry to the state, and if there is an error, prune that branch.
if object if let Err(err) = object.apply(entry, siblings.map(|(k, n)| (k, &n.value)), store) {
.apply(entry, siblings.map(|(k, n)| (k, &n.value)), store) log::debug!("Application of entry {} returned error: {err}", entry.id);
.is_err()
{
return ControlFlow::Break(()); return ControlFlow::Break(());
} }
ControlFlow::Continue(()) ControlFlow::Continue(())

View File

@ -45,6 +45,12 @@ pub struct Reference {
pub target: Commit, pub target: Commit,
} }
impl std::fmt::Display for Reference {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} @ {}", self.name, self.target.id)
}
}
/// A [`Commit`] that holds the data for a given [`crate::CollaborativeObject`]. /// A [`Commit`] that holds the data for a given [`crate::CollaborativeObject`].
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Commit { pub struct Commit {