Skip to content

Commit 3c9ec04

Browse files
authored
Remove unwrap() in sonic-host-services (#331)
unwrap() function may crash in runtime. 1. For constant value which is safe, we use expect() instead of unwrap(), so any future programming mistake on changing the constant value could get better crash message. Current value will not trigger crash. 2. For float may be NaN, handle it safely 3. Handle initialization errors gracefully
1 parent 2adb78a commit 3c9ec04

File tree

1 file changed

+12
-7
lines changed
  • crates/procdockerstatsd-rs/src

1 file changed

+12
-7
lines changed

crates/procdockerstatsd-rs/src/main.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ fn get_terminal_name(pid: u32) -> String {
7070
}
7171

7272
fn convert_to_bytes(value: &str) -> u64 {
73-
static RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(\d+\.?\d*)([a-zA-Z]+)").unwrap());
73+
static RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(\d+\.?\d*)([a-zA-Z]+)").expect("valid regex pattern"));
7474
if let Some(caps) = RE.captures(value) {
7575
let num: f64 = caps[1].parse().unwrap_or(0.0);
7676
let unit = &caps[2];
@@ -191,14 +191,17 @@ impl ProcDockerStats {
191191
ProcessStatus::Unknown(_) | ProcessStatus::Zombie => continue,
192192
_ => {
193193
let cpu = process_obj.cpu_usage();
194-
valid_processes.push((cpu, process_obj));
194+
// Treat NaN as 0.0 for sorting purposes
195+
let cpu_safe = if cpu.is_nan() { 0.0 } else { cpu };
196+
valid_processes.push((cpu_safe, process_obj));
195197
}
196198
}
197199
}
198200
// Partial sort: only need top 1024, so use select_nth_unstable for O(n) instead of O(n log n)
199201
let limit = 1024.min(valid_processes.len());
200202
if limit > 0 {
201-
valid_processes.select_nth_unstable_by(limit - 1, |a, b| b.0.partial_cmp(&a.0).unwrap());
203+
// Safe to use total_cmp now since we've already handled NaN above
204+
valid_processes.select_nth_unstable_by(limit - 1, |a, b| b.0.total_cmp(&a.0));
202205
}
203206
let top_processes = valid_processes.iter().take(limit).map(|(_, p)| *p);
204207

@@ -353,14 +356,15 @@ impl ProcDockerStats {
353356
}
354357
}
355358

356-
fn main() {
359+
fn main() -> Result<(), Box<dyn std::error::Error>> {
357360
// Initialize tracing with syslog like sonic-ctrmgrd-rs example
358-
let identity = CString::new("procdockerstatsd").unwrap();
361+
let identity = CString::new("procdockerstatsd")
362+
.map_err(|e| format!("invalid identity string: {}", e))?;
359363
let syslog = syslog_tracing::Syslog::new(
360364
identity,
361365
syslog_tracing::Options::LOG_PID,
362366
syslog_tracing::Facility::Daemon
363-
).unwrap();
367+
).ok_or("failed to initialize syslog")?;
364368
tracing_subscriber::fmt()
365369
.with_writer(syslog)
366370
.with_ansi(false)
@@ -371,6 +375,7 @@ fn main() {
371375

372376
info!("Starting up procdockerstatsd daemon");
373377

374-
let mut daemon = ProcDockerStats::new().expect("Failed to initialize daemon");
378+
let mut daemon = ProcDockerStats::new()?;
375379
daemon.run();
380+
Ok(())
376381
}

0 commit comments

Comments
 (0)