From 6d4da1b7da76abcd32d4f414d95dcf1b5c5b274a Mon Sep 17 00:00:00 2001 From: Christoffer Martinsson Date: Sun, 23 Nov 2025 14:45:00 +0100 Subject: [PATCH] Add robust error handling to prevent dashboard crashes Added comprehensive error handling to storage metrics parsing to prevent dashboard crashes when encountering unexpected metric formats or parsing errors. Dashboard now continues gracefully with empty storage display instead of crashing, improving reliability during metric format changes. - Wrapped storage metric parsing in panic recovery - Added logging for metric parsing failures - Dashboard shows empty storage on errors instead of crashing - Ensures dashboard remains functional during agent updates --- Cargo.lock | 6 +++--- agent/Cargo.toml | 2 +- dashboard/Cargo.toml | 2 +- dashboard/src/ui/widgets/system.rs | 22 +++++++++++++++++----- shared/Cargo.toml | 2 +- 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3be2bb4..0564330 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -279,7 +279,7 @@ checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "cm-dashboard" -version = "0.1.109" +version = "0.1.110" dependencies = [ "anyhow", "chrono", @@ -301,7 +301,7 @@ dependencies = [ [[package]] name = "cm-dashboard-agent" -version = "0.1.109" +version = "0.1.110" dependencies = [ "anyhow", "async-trait", @@ -324,7 +324,7 @@ dependencies = [ [[package]] name = "cm-dashboard-shared" -version = "0.1.109" +version = "0.1.110" dependencies = [ "chrono", "serde", diff --git a/agent/Cargo.toml b/agent/Cargo.toml index 514273a..82aaea5 100644 --- a/agent/Cargo.toml +++ b/agent/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cm-dashboard-agent" -version = "0.1.110" +version = "0.1.111" edition = "2021" [dependencies] diff --git a/dashboard/Cargo.toml b/dashboard/Cargo.toml index 4138383..d4ff14c 100644 --- a/dashboard/Cargo.toml +++ b/dashboard/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cm-dashboard" -version = "0.1.110" +version = "0.1.111" edition = "2021" [dependencies] diff --git a/dashboard/src/ui/widgets/system.rs b/dashboard/src/ui/widgets/system.rs index fc58066..63c78c5 100644 --- a/dashboard/src/ui/widgets/system.rs +++ b/dashboard/src/ui/widgets/system.rs @@ -157,13 +157,17 @@ impl SystemWidget { } } - /// Parse storage metrics into pools and drives + /// Parse storage metrics into pools and drives fn update_storage_from_metrics(&mut self, metrics: &[&Metric]) { let mut pools: std::collections::HashMap = std::collections::HashMap::new(); for metric in metrics { if metric.name.starts_with("disk_") { - if let Some(pool_name) = self.extract_pool_name(&metric.name) { + // Wrap individual metric parsing in error handling + if let Ok(pool_name) = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { + self.extract_pool_name(&metric.name) + })) { + if let Some(pool_name) = pool_name { let mount_point = self.get_mount_point_for_pool(&pool_name); let pool = pools.entry(pool_name.clone()).or_insert_with(|| StoragePool { name: pool_name.clone(), @@ -328,7 +332,10 @@ impl SystemWidget { } } } - } + } // Close pool_name Some check + } else { + tracing::warn!("Failed to extract pool name from metric: {}", metric.name); + } // Close error handling for extract_pool_name } } @@ -705,8 +712,13 @@ impl Widget for SystemWidget { } } - // Update storage from all disk metrics - self.update_storage_from_metrics(metrics); + // Update storage from all disk metrics (with error handling) + if let Err(e) = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { + self.update_storage_from_metrics(metrics); + })) { + tracing::error!("Storage metrics parsing failed, continuing with empty storage: {:?}", e); + self.storage_pools = Vec::new(); + } } } diff --git a/shared/Cargo.toml b/shared/Cargo.toml index 1dc5639..10223f5 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cm-dashboard-shared" -version = "0.1.110" +version = "0.1.111" edition = "2021" [dependencies]