From a65ac048cbda3473e7b372375d33e3a357965492 Mon Sep 17 00:00:00 2001 From: Lorenz Leutgeb Date: Mon, 30 Mar 2026 18:16:03 +0200 Subject: [PATCH] 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. --- crates/radicle-cob/src/change_graph.rs | 19 ++++++++++++------- crates/radicle-cob/src/object/storage.rs | 6 ++++++ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/crates/radicle-cob/src/change_graph.rs b/crates/radicle-cob/src/change_graph.rs index 6dbfbdf6..b7923e43 100644 --- a/crates/radicle-cob/src/change_graph.rs +++ b/crates/radicle-cob/src/change_graph.rs @@ -39,12 +39,18 @@ impl ChangeGraph { where S: change::Storage, { - log::debug!(target: "cob", "Loading object of type {typename} at {oid}"); + let tip_refs = tip_refs.collect::>(); + + 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::>().join(", ")); + } let mut graph: Dag = Dag::new(); // 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(); while let Some(child_id) = child_ids.pop() { @@ -113,13 +119,12 @@ impl ChangeGraph { |_, entry, siblings| { // Check the entry signatures are valid. if !entry.valid_signatures() { + log::debug!("Signature verification failed for entry {}.", entry.id); return ControlFlow::Break(()); } - // Apply the entry to the state, and if there's an error, prune that branch. - if object - .apply(entry, siblings.map(|(k, n)| (k, &n.value)), store) - .is_err() - { + // Apply the entry to the state, and if there is an error, prune that branch. + if let Err(err) = object.apply(entry, siblings.map(|(k, n)| (k, &n.value)), store) { + log::debug!("Application of entry {} returned error: {err}", entry.id); return ControlFlow::Break(()); } ControlFlow::Continue(()) diff --git a/crates/radicle-cob/src/object/storage.rs b/crates/radicle-cob/src/object/storage.rs index a23d468a..f2b6bfab 100644 --- a/crates/radicle-cob/src/object/storage.rs +++ b/crates/radicle-cob/src/object/storage.rs @@ -45,6 +45,12 @@ pub struct Reference { 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`]. #[derive(Clone, Debug)] pub struct Commit {