feat: log each kind of unhandled event once per run

Also raise to debug level so they're not so hidden.
This commit is contained in:
Lars Wirzenius
2026-06-30 09:46:28 +03:00
parent 21d234ad68
commit 2bae93c019
5 changed files with 63 additions and 15 deletions
+4 -2
View File
@@ -1,4 +1,4 @@
use std::io::Write;
use std::{collections::HashSet, io::Write};
use clap::ValueEnum;
@@ -436,7 +436,9 @@ impl Leaf for CiEvents {
let mut ci_events: Vec<CiEvent> = vec![];
for node_event in node_events.iter() {
if let Ok(mut cevs) = CiEvent::from_node_event(node_event, radicle.profile()) {
if let Ok(mut cevs) =
CiEvent::from_node_event(node_event, radicle.profile(), &mut HashSet::new())
{
ci_events.append(&mut cevs);
}
}
+19 -10
View File
@@ -1,5 +1,5 @@
use std::{
collections::BTreeMap,
collections::{BTreeMap, HashSet},
path::{Path, PathBuf},
str::FromStr,
};
@@ -24,6 +24,7 @@ use radicle::{
use crate::{
logger,
msg::RunId,
node_event_source::NodeEventKind,
refs::{GenericRefName, TagName, ref_string},
};
@@ -286,7 +287,11 @@ impl CiEvent {
}
#[allow(clippy::unwrap_used)]
pub fn from_node_event(event: &Event, profile: &Profile) -> Result<Vec<Self>, CiEventError> {
pub fn from_node_event(
event: &Event,
profile: &Profile,
unhandled: &mut HashSet<NodeEventKind>,
) -> Result<Vec<Self>, CiEventError> {
let (rid, updates) = match event {
Event::RefsFetched {
remote: _,
@@ -337,7 +342,11 @@ impl CiEvent {
(*rid, &updates.collect())
}
_ => {
logger::node_event_not_handled(event);
let kind = NodeEventKind::from(event);
if !unhandled.contains(&kind) {
unhandled.insert(kind);
logger::node_event_not_handled(event);
}
return Ok(vec![]);
}
};
@@ -595,7 +604,7 @@ mod test {
rid: rid(),
updated: vec![],
};
let result = CiEvent::from_node_event(&event, &profile);
let result = CiEvent::from_node_event(&event, &profile, &mut HashSet::new());
assert!(result.is_ok());
assert_eq!(result.unwrap(), vec![]);
Ok(())
@@ -614,7 +623,7 @@ mod test {
}],
};
let result = CiEvent::from_node_event(&event, &profile);
let result = CiEvent::from_node_event(&event, &profile, &mut HashSet::new());
assert!(result.is_ok());
assert_eq!(result.unwrap(), vec![]);
Ok(())
@@ -634,7 +643,7 @@ mod test {
oid,
}],
};
let x = CiEvent::from_node_event(&event, &profile);
let x = CiEvent::from_node_event(&event, &profile, &mut HashSet::new());
eprintln!("result: {x:#?}");
match x {
Err(_) => panic!("should succeed"),
@@ -671,7 +680,7 @@ mod test {
new: oid,
}],
};
let x = CiEvent::from_node_event(&event, &profile);
let x = CiEvent::from_node_event(&event, &profile, &mut HashSet::new());
eprintln!("result: {x:#?}");
match x {
Err(_) => panic!("should succeed"),
@@ -711,7 +720,7 @@ mod test {
oid,
}],
};
let x = CiEvent::from_node_event(&event, &profile);
let x = CiEvent::from_node_event(&event, &profile, &mut HashSet::new());
eprintln!("result: {x:#?}");
match x {
Err(_) => panic!("should succeed"),
@@ -745,7 +754,7 @@ mod test {
oid,
}],
};
let x = CiEvent::from_node_event(&event, &profile);
let x = CiEvent::from_node_event(&event, &profile, &mut HashSet::new());
eprintln!("result: {x:#?}");
match x {
Err(_) => panic!("should succeed"),
@@ -783,7 +792,7 @@ mod test {
new: oid,
}],
};
let x = CiEvent::from_node_event(&event, &profile);
let x = CiEvent::from_node_event(&event, &profile, &mut HashSet::new());
eprintln!("result: {x:#?}");
match x {
Err(_) => panic!("should succeed"),
+3 -2
View File
@@ -1,4 +1,4 @@
use std::fmt;
use std::{collections::HashSet, fmt};
use radicle::Profile;
@@ -25,6 +25,7 @@ impl<'a> CiEventSource<'a> {
pub fn event(&mut self) -> Result<Option<Vec<CiEvent>>, CiEventSourceError> {
let result = self.source.node_event();
let mut unhandled = HashSet::new();
match result {
Err(err) if matches!(err, NodeEventError::BrokenConnection) => {
logger::ci_event_source_disconnected();
@@ -43,7 +44,7 @@ impl<'a> CiEventSource<'a> {
Ok(None)
}
Ok(Some(event)) => {
let ci_events = CiEvent::from_node_event(&event, self.profile)
let ci_events = CiEvent::from_node_event(&event, self.profile, &mut unhandled)
.map_err(CiEventSourceError::CiEvent)?;
if !ci_events.is_empty() {
logger::ci_event_source_got_events(&ci_events);
+1 -1
View File
@@ -359,7 +359,7 @@ pub fn node_event_source_eof(source: &NodeEventSource) {
}
pub fn node_event_not_handled(event: &Event) {
trace!(
debug!(
msg_id = ?Id::NodeEventNotHandled,
kind = %Kind::Debug,
?event,
+36
View File
@@ -80,6 +80,42 @@ impl fmt::Debug for NodeEventSource {
}
}
/// Kind of node event.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum NodeEventKind {
RefsFetched,
RefsSynced,
SeedDiscovered,
SeedDropped,
PeerConnected,
LocalRefsAnnounced,
InventoryAnnounced,
RefsAnnounced,
NodeAnnounced,
UploadPack,
CanonicalRefUpdated,
Other,
}
impl From<&Event> for NodeEventKind {
fn from(value: &Event) -> Self {
match value {
Event::RefsFetched { .. } => Self::RefsFetched,
Event::RefsSynced { .. } => Self::RefsFetched,
Event::SeedDiscovered { .. } => Self::SeedDiscovered,
Event::SeedDropped { .. } => Self::SeedDropped,
Event::PeerConnected { .. } => Self::PeerConnected,
Event::LocalRefsAnnounced { .. } => Self::LocalRefsAnnounced,
Event::InventoryAnnounced { .. } => Self::InventoryAnnounced,
Event::RefsAnnounced { .. } => Self::RefsAnnounced,
Event::NodeAnnounced { .. } => Self::NodeAnnounced,
Event::UploadPack { .. } => Self::UploadPack,
Event::CanonicalRefUpdated { .. } => Self::CanonicalRefUpdated,
_ => Self::Other,
}
}
}
/// Possible errors from accessing the local Radicle node.
#[derive(Debug, thiserror::Error)]
pub enum NodeEventError {