Add robust error handling to prevent dashboard crashes
All checks were successful
Build and Release / build-and-release (push) Successful in 2m9s

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
This commit is contained in:
Christoffer Martinsson 2025-11-23 14:45:00 +01:00
parent 1e7f1616aa
commit 6d4da1b7da
5 changed files with 23 additions and 11 deletions

6
Cargo.lock generated
View File

@ -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",

View File

@ -1,6 +1,6 @@
[package]
name = "cm-dashboard-agent"
version = "0.1.110"
version = "0.1.111"
edition = "2021"
[dependencies]

View File

@ -1,6 +1,6 @@
[package]
name = "cm-dashboard"
version = "0.1.110"
version = "0.1.111"
edition = "2021"
[dependencies]

View File

@ -163,7 +163,11 @@ impl SystemWidget {
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
// 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();
}
}
}

View File

@ -1,6 +1,6 @@
[package]
name = "cm-dashboard-shared"
version = "0.1.110"
version = "0.1.111"
edition = "2021"
[dependencies]