From b9186aa6611388102e632ee34645c48f41064ef0 Mon Sep 17 00:00:00 2001
From: Federico Lolli <federico.lolli@skywarder.eu>
Date: Wed, 20 Mar 2024 17:30:01 +0100
Subject: [PATCH] Added fancy error handling with color_eyre

---
 on-host/Cargo.toml   |  1 +
 on-host/src/main.rs  | 25 +++++++++++++++----------
 on-host/src/utils.rs |  9 +++++----
 3 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/on-host/Cargo.toml b/on-host/Cargo.toml
index 65ce708..d7611a0 100644
--- a/on-host/Cargo.toml
+++ b/on-host/Cargo.toml
@@ -7,6 +7,7 @@ edition = "2021"
 
 [dependencies]
 clap = { version = "4.4.11", features = ["derive"] }
+color-eyre = { version = "0.6.3", default-features = false }
 csv = "1.3.0"
 log = "0.4.20"
 serde = { version = "1.0.193", features = ["derive"] }
diff --git a/on-host/src/main.rs b/on-host/src/main.rs
index 49ba42d..56cc1f3 100644
--- a/on-host/src/main.rs
+++ b/on-host/src/main.rs
@@ -9,6 +9,7 @@ use std::{
 };
 
 use clap::Parser;
+use color_eyre::eyre::{Context, Result};
 use log::{debug, error, info, warn};
 use serialport::SerialPort;
 use skyward_mavlink::{
@@ -24,7 +25,8 @@ use crate::{
 
 const ACK: u8 = 0x06;
 
-fn main() {
+fn main() -> Result<()> {
+    color_eyre::install()?;
     let args: Cli = Cli::parse();
 
     let lvl = if args.verbose {
@@ -38,8 +40,7 @@ fn main() {
         .with_level(lvl)
         .with_local_timestamps()
         .env()
-        .init()
-        .unwrap();
+        .init()?;
 
     let mut packets = Vec::new();
 
@@ -56,7 +57,7 @@ fn main() {
     // Open the first serialport available.
     let port_name = if let Some(name) = args.port {
         name
-    } else if let Some(name) = get_first_stm32_serial_port() {
+    } else if let Some(name) = get_first_stm32_serial_port()? {
         debug!("found STM32 device on {}", name);
         name
     } else {
@@ -66,8 +67,8 @@ fn main() {
     debug!("connecting to serial port {}...", port_name);
     let mut port = serialport::new(port_name, args.baud_rate)
         .open()
-        .expect("Failed to open serial port");
-    let mut write_port = port.try_clone().expect("Failed to clone");
+        .wrap_err("Failed to open serial port")?;
+    let mut write_port = port.try_clone()?;
 
     // let mut iter = packets.into_iter();
 
@@ -82,7 +83,7 @@ fn main() {
             times.push(t.elapsed().as_millis());
         }
         start = Some(Instant::now());
-        write_port.write_packet(packet.to_owned());
+        write_port.write_packet(packet.to_owned())?;
         debug!(
             "sent packet ({}/{})",
             packets.sent_packets(),
@@ -97,6 +98,8 @@ fn main() {
 
     info!("sent {} packets", packets.sent_packets());
     print_stats(times);
+
+    Ok(())
 }
 
 /// Wait for ACK signal from the device
@@ -125,12 +128,14 @@ fn wait_for_ack(port: &mut Box<dyn SerialPort>, buffer: &mut [u8]) {
 }
 
 trait MavLinkPort {
-    fn write_packet(&mut self, packet: MavMessage);
+    fn write_packet(&mut self, packet: MavMessage) -> Result<()>;
 }
 
 impl<T: AsRef<dyn SerialPort> + std::io::Write> MavLinkPort for T {
-    fn write_packet(&mut self, packet: MavMessage) {
+    fn write_packet(&mut self, packet: MavMessage) -> Result<()> {
         let header = MavHeader::default();
-        write_v1_msg(self, header, &packet).expect("Failed to write to serial port");
+        write_v1_msg(self, header, &packet)
+            .wrap_err("Failed to write mavlink message to serial port")?;
+        Ok(())
     }
 }
diff --git a/on-host/src/utils.rs b/on-host/src/utils.rs
index 1c76055..e8e6c3d 100644
--- a/on-host/src/utils.rs
+++ b/on-host/src/utils.rs
@@ -1,18 +1,19 @@
+use color_eyre::eyre::{Context, Result};
 use log::info;
 
 /// Get the first serial port that contains "STM32" or "ST-LINK" in its product name
-pub fn get_first_stm32_serial_port() -> Option<String> {
-    let ports = serialport::available_ports().expect("No serial ports found!");
+pub fn get_first_stm32_serial_port() -> Result<Option<String>> {
+    let ports = serialport::available_ports().wrap_err("No serial ports found!")?;
     for port in ports {
         if let serialport::SerialPortType::UsbPort(info) = port.port_type {
             if let Some(p) = info.product {
                 if p.contains("STM32") || p.contains("ST-LINK") {
-                    return Some(port.port_name);
+                    return Ok(Some(port.port_name));
                 }
             }
         }
     }
-    None
+    Ok(None)
 }
 
 /// print stats (mean, median, std, etc)
-- 
GitLab