diff --git a/src/adc.rs b/src/adc.rs index f2c79247..634dc624 100644 --- a/src/adc.rs +++ b/src/adc.rs @@ -83,7 +83,7 @@ impl Adc { let adc = Self { usb_host_curr: AdcChannel { - fast: stm32_thread.clone().get_channel("usb-host-curr").unwrap(), + fast: stm32_thread.clone().get_channel("usb-host-curr")?, topic: bb.topic( "/v1/usb/host/total/feedback/current", true, @@ -94,7 +94,7 @@ impl Adc { ), }, usb_host1_curr: AdcChannel { - fast: stm32_thread.clone().get_channel("usb-host1-curr").unwrap(), + fast: stm32_thread.clone().get_channel("usb-host1-curr")?, topic: bb.topic( "/v1/usb/host/port1/feedback/current", true, @@ -105,7 +105,7 @@ impl Adc { ), }, usb_host2_curr: AdcChannel { - fast: stm32_thread.clone().get_channel("usb-host2-curr").unwrap(), + fast: stm32_thread.clone().get_channel("usb-host2-curr")?, topic: bb.topic( "/v1/usb/host/port2/feedback/current", true, @@ -116,7 +116,7 @@ impl Adc { ), }, usb_host3_curr: AdcChannel { - fast: stm32_thread.clone().get_channel("usb-host3-curr").unwrap(), + fast: stm32_thread.clone().get_channel("usb-host3-curr")?, topic: bb.topic( "/v1/usb/host/port3/feedback/current", true, @@ -127,7 +127,7 @@ impl Adc { ), }, out0_volt: AdcChannel { - fast: stm32_thread.clone().get_channel("out0-volt").unwrap(), + fast: stm32_thread.clone().get_channel("out0-volt")?, topic: bb.topic( "/v1/output/out_0/feedback/voltage", true, @@ -138,7 +138,7 @@ impl Adc { ), }, out1_volt: AdcChannel { - fast: stm32_thread.clone().get_channel("out1-volt").unwrap(), + fast: stm32_thread.clone().get_channel("out1-volt")?, topic: bb.topic( "/v1/output/out_1/feedback/voltage", true, @@ -149,7 +149,7 @@ impl Adc { ), }, iobus_curr: AdcChannel { - fast: stm32_thread.clone().get_channel("iobus-curr").unwrap(), + fast: stm32_thread.clone().get_channel("iobus-curr")?, topic: bb.topic( "/v1/iobus/feedback/current", true, @@ -160,7 +160,7 @@ impl Adc { ), }, iobus_volt: AdcChannel { - fast: stm32_thread.clone().get_channel("iobus-volt").unwrap(), + fast: stm32_thread.clone().get_channel("iobus-volt")?, topic: bb.topic( "/v1/iobus/feedback/voltage", true, @@ -171,7 +171,7 @@ impl Adc { ), }, pwr_volt: AdcChannel { - fast: powerboard_thread.clone().get_channel("pwr-volt").unwrap(), + fast: powerboard_thread.clone().get_channel("pwr-volt")?, topic: bb.topic( "/v1/dut/feedback/voltage", true, @@ -182,7 +182,7 @@ impl Adc { ), }, pwr_curr: AdcChannel { - fast: powerboard_thread.get_channel("pwr-curr").unwrap(), + fast: powerboard_thread.get_channel("pwr-curr")?, topic: bb.topic( "/v1/dut/feedback/current", true, diff --git a/src/dbus.rs b/src/dbus.rs index a8e8872a..38a0c28b 100644 --- a/src/dbus.rs +++ b/src/dbus.rs @@ -15,6 +15,7 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +use anyhow::Result; use async_std::sync::Arc; use crate::broker::{BrokerBuilder, Topic}; @@ -22,7 +23,7 @@ use crate::led::BlinkPattern; #[cfg(feature = "demo_mode")] mod zb { - pub type Result = std::result::Result; + use anyhow::Result; pub struct Connection; pub struct ConnectionBuilder; @@ -51,7 +52,7 @@ mod zb { pub use zbus::*; } -use zb::{Connection, ConnectionBuilder, Result}; +use zb::{Connection, ConnectionBuilder}; pub mod networkmanager; pub mod rauc; @@ -76,20 +77,17 @@ impl DbusSession { bb: &mut BrokerBuilder, led_dut: Arc>, led_uplink: Arc>, - ) -> Self { + ) -> Result { let tacd = Tacd::new(); - let conn_builder = ConnectionBuilder::system() - .unwrap() - .name("de.pengutronix.tacd") - .unwrap(); + let conn_builder = ConnectionBuilder::system()?.name("de.pengutronix.tacd")?; - let conn = Arc::new(tacd.serve(conn_builder).build().await.unwrap()); + let conn = Arc::new(tacd.serve(conn_builder).build().await?); - Self { + Ok(Self { network: Network::new(bb, &conn, led_dut, led_uplink), rauc: Rauc::new(bb, &conn), systemd: Systemd::new(bb, &conn).await, - } + }) } } diff --git a/src/digital_io.rs b/src/digital_io.rs index 63eb9c7e..2eabbd2e 100644 --- a/src/digital_io.rs +++ b/src/digital_io.rs @@ -15,6 +15,7 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +use anyhow::{Context, Result}; use async_std::prelude::*; use async_std::sync::Arc; use async_std::task::spawn; @@ -58,27 +59,26 @@ fn handle_line_wo( initial: bool, inverted: bool, led_topic: Option>>, -) -> Arc> { +) -> Result>> { let topic = bb.topic_rw(path, Some(initial)); - let line = find_line(line_name).unwrap(); - let dst = line - .request(LineRequestFlags::OUTPUT, (initial ^ inverted) as _, "tacd") - .unwrap(); + let line = find_line(line_name).with_context(|| format!("couldn't find line {line_name}"))?; + let dst = line.request(LineRequestFlags::OUTPUT, (initial ^ inverted) as _, "tacd")?; let (mut src, _) = topic.clone().subscribe_unbounded(); spawn(async move { while let Some(ev) = src.next().await { - dst.set_value((ev ^ inverted) as _).unwrap(); + dst.set_value((ev ^ inverted) as _)?; if let Some(led) = &led_topic { let pattern = BlinkPattern::solid(if ev { 1.0 } else { 0.0 }); led.set(pattern); } } + anyhow::Ok(()) }); - topic + Ok(topic) } impl DigitalIo { @@ -86,7 +86,7 @@ impl DigitalIo { bb: &mut BrokerBuilder, led_0: Arc>, led_1: Arc>, - ) -> Self { + ) -> Result { let out_0 = handle_line_wo( bb, "/v1/output/out_0/asserted", @@ -94,7 +94,7 @@ impl DigitalIo { false, false, Some(led_0), - ); + )?; let out_1 = handle_line_wo( bb, @@ -103,16 +103,16 @@ impl DigitalIo { false, false, Some(led_1), - ); + )?; - let uart_rx_en = handle_line_wo(bb, "/v1/uart/rx/enabled", "UART_RX_EN", true, true, None); - let uart_tx_en = handle_line_wo(bb, "/v1/uart/tx/enabled", "UART_TX_EN", true, true, None); + let uart_rx_en = handle_line_wo(bb, "/v1/uart/rx/enabled", "UART_RX_EN", true, true, None)?; + let uart_tx_en = handle_line_wo(bb, "/v1/uart/tx/enabled", "UART_TX_EN", true, true, None)?; - Self { + Ok(Self { out_0, out_1, uart_rx_en, uart_tx_en, - } + }) } } diff --git a/src/digital_io/gpio/demo_mode.rs b/src/digital_io/gpio/demo_mode.rs index 1c438a3d..26b90c68 100644 --- a/src/digital_io/gpio/demo_mode.rs +++ b/src/digital_io/gpio/demo_mode.rs @@ -27,33 +27,23 @@ pub struct LineHandle { } impl LineHandle { - pub fn set_value(&self, val: u8) -> Result<(), ()> { + pub fn set_value(&self, val: u8) -> Result<()> { // This does not actually set up any IIO things. // It is just a hack to let adc/iio/demo_mode.rs // communicate with this function so that toggling an output // has an effect on the measured values. - let iio_thread_stm32 = block_on(IioThread::new_stm32()).unwrap(); - let iio_thread_pwr = block_on(IioThread::new_powerboard()).unwrap(); + let iio_thread_stm32 = block_on(IioThread::new_stm32())?; + let iio_thread_pwr = block_on(IioThread::new_powerboard())?; match self.name.as_str() { - "OUT_0" => iio_thread_stm32 - .get_channel("out0-volt") - .unwrap() - .set(val != 0), - "OUT_1" => iio_thread_stm32 - .get_channel("out1-volt") - .unwrap() - .set(val != 0), + "OUT_0" => iio_thread_stm32.get_channel("out0-volt")?.set(val != 0), + "OUT_1" => iio_thread_stm32.get_channel("out1-volt")?.set(val != 0), "DUT_PWR_EN" => { iio_thread_pwr .clone() - .get_channel("pwr-curr") - .unwrap() - .set(val == 0); - iio_thread_pwr - .get_channel("pwr-volt") - .unwrap() + .get_channel("pwr-curr")? .set(val == 0); + iio_thread_pwr.get_channel("pwr-volt")?.set(val == 0); } _ => {} } diff --git a/src/digital_io/gpio/test.rs b/src/digital_io/gpio/test.rs index d67a8ca7..27d8a918 100644 --- a/src/digital_io/gpio/test.rs +++ b/src/digital_io/gpio/test.rs @@ -33,7 +33,7 @@ pub struct LineHandle { } impl LineHandle { - pub fn set_value(&self, val: u8) -> Result<(), ()> { + pub fn set_value(&self, val: u8) -> Result<()> { println!("GPIO simulation set {} to {}", self.name, val); self.val.store(val, Ordering::Relaxed); Ok(()) diff --git a/src/dut_power.rs b/src/dut_power.rs index c9376886..f75ecb1a 100644 --- a/src/dut_power.rs +++ b/src/dut_power.rs @@ -19,7 +19,7 @@ use std::sync::atomic::{AtomicU32, AtomicU8, Ordering}; use std::thread; use std::time::{Duration, Instant}; -use anyhow::{anyhow, Result}; +use anyhow::{anyhow, Context, Result}; use async_std::channel::bounded; use async_std::prelude::*; use async_std::sync::{Arc, Weak}; @@ -44,13 +44,13 @@ mod prio { mod prio { use std::convert::TryFrom; - use anyhow::{anyhow, Result}; + use anyhow::{anyhow, Error, Result}; use thread_priority::*; pub fn realtime_priority() -> Result<()> { set_thread_priority_and_policy( thread_native_id(), - ThreadPriority::Crossplatform(ThreadPriorityValue::try_from(10).unwrap()), + ThreadPriority::Crossplatform(ThreadPriorityValue::try_from(10).map_err(Error::msg)?), ThreadSchedulePolicy::Realtime(RealtimeThreadSchedulePolicy::Fifo), ) .map_err(|e| anyhow!("Failed to set up realtime priority {e:?}")) @@ -236,10 +236,11 @@ fn turn_off_with_reason( pwr_line: &LineHandle, discharge_line: &LineHandle, fail_state: &AtomicU8, -) { - pwr_line.set_value(1 - PWR_LINE_ASSERTED).unwrap(); - discharge_line.set_value(DISCHARGE_LINE_ASSERTED).unwrap(); +) -> Result<()> { + pwr_line.set_value(1 - PWR_LINE_ASSERTED)?; + discharge_line.set_value(DISCHARGE_LINE_ASSERTED)?; fail_state.store(reason as u8, Ordering::Relaxed); + Ok(()) } /// Labgrid has a fixed assumption of how a REST based power port should work. @@ -334,14 +335,12 @@ impl DutPwrThread { let request = Arc::new(AtomicU8::new(OutputRequest::Idle as u8)); let state = Arc::new(AtomicU8::new(OutputState::Off as u8)); - thread_res_tx - .try_send(Ok((tick, request.clone(), state.clone()))) - .unwrap(); + thread_res_tx.try_send(Ok((tick, request.clone(), state.clone())))?; (tick_weak, request, state) } Err(e) => { - thread_res_tx.try_send(Err(e)).unwrap(); + thread_res_tx.try_send(Err(e))?; panic!() } }; @@ -378,7 +377,7 @@ impl DutPwrThread { &pwr_line, &discharge_line, &state, - ); + )?; } else { // We have a fresh ADC value. Signal "everything is well" // to the watchdog task. @@ -415,7 +414,7 @@ impl DutPwrThread { &pwr_line, &discharge_line, &state, - ); + )?; continue; } @@ -429,7 +428,7 @@ impl DutPwrThread { &pwr_line, &discharge_line, &state, - ); + )?; continue; } @@ -442,7 +441,7 @@ impl DutPwrThread { &pwr_line, &discharge_line, &state, - ); + )?; continue; } @@ -452,32 +451,31 @@ impl DutPwrThread { match req { OutputRequest::Idle => {} OutputRequest::On => { - discharge_line - .set_value(1 - DISCHARGE_LINE_ASSERTED) - .unwrap(); - pwr_line.set_value(PWR_LINE_ASSERTED).unwrap(); + discharge_line.set_value(1 - DISCHARGE_LINE_ASSERTED)?; + pwr_line.set_value(PWR_LINE_ASSERTED)?; state.store(OutputState::On as u8, Ordering::Relaxed); } OutputRequest::Off => { - discharge_line.set_value(DISCHARGE_LINE_ASSERTED).unwrap(); - pwr_line.set_value(1 - PWR_LINE_ASSERTED).unwrap(); + discharge_line.set_value(DISCHARGE_LINE_ASSERTED)?; + pwr_line.set_value(1 - PWR_LINE_ASSERTED)?; state.store(OutputState::Off as u8, Ordering::Relaxed); } OutputRequest::OffFloating => { - discharge_line - .set_value(1 - DISCHARGE_LINE_ASSERTED) - .unwrap(); - pwr_line.set_value(1 - PWR_LINE_ASSERTED).unwrap(); + discharge_line.set_value(1 - DISCHARGE_LINE_ASSERTED)?; + pwr_line.set_value(1 - PWR_LINE_ASSERTED)?; state.store(OutputState::OffFloating as u8, Ordering::Relaxed); } } } // Make sure to enter fail safe mode before leaving the thread - turn_off_with_reason(OutputState::Off, &pwr_line, &discharge_line, &state); + turn_off_with_reason(OutputState::Off, &pwr_line, &discharge_line, &state) })?; - let (tick, request, state) = thread_res_rx.next().await.unwrap()?; + let (tick, request, state) = thread_res_rx + .next() + .await + .context("didn't receive thread result")??; // The request and state topic use the same external path, this way one // can e.g. publish "On" to the topic and be sure that the output is @@ -572,12 +570,12 @@ mod tests { #[test] fn failsafe() { - let pwr_line = find_line("DUT_PWR_EN").unwrap(); - let discharge_line = find_line("DUT_PWR_DISCH").unwrap(); + let pwr_line = find_line("DUT_PWR_EN").expect("couldn't find DUT_PWR_EN"); + let discharge_line = find_line("DUT_PWR_DISCH").expect("couldn't find DUT_PWR_DISCH"); let (adc, dut_pwr, led) = { let mut bb = BrokerBuilder::new(); - let adc = block_on(Adc::new(&mut bb)).unwrap(); + let adc = block_on(Adc::new(&mut bb)).expect("couldn't create ADC"); let led = Topic::anonymous(None); let dut_pwr = block_on(DutPwrThread::new( @@ -586,7 +584,7 @@ mod tests { adc.pwr_curr.clone(), led.clone(), )) - .unwrap(); + .expect("couldn't start DUT PWR thread"); (adc, dut_pwr, led) }; diff --git a/src/http_server.rs b/src/http_server.rs index 94d1a7be..a662ca96 100644 --- a/src/http_server.rs +++ b/src/http_server.rs @@ -18,6 +18,7 @@ use std::fs::write; use std::net::TcpListener; +use anyhow::{Context, Result}; use tide::{Body, Response, Server}; mod serve_dir; @@ -60,30 +61,30 @@ pub struct HttpServer { } impl HttpServer { - pub fn new() -> Self { - let mut this = Self { + pub fn new() -> Result { + let mut server = Self { listeners: Vec::new(), server: tide::new(), }; // Open [::]:80 / [::]:8080. This, somewhat confusingly also listens on // 0.0.0.0 and not only on IPv6. - this.listeners.push( - TcpListener::bind(FALLBACK_PORT).expect( - "Could not bind web API to port, is there already another service running?", - ), - ); + server + .listeners + .push(TcpListener::bind(FALLBACK_PORT).with_context(|| { + "Could not bind web API to port, is there already another service running?" + })?); - this.expose_openapi_json(); - this.expose_dir(WEBUI_DIR, "/", false); - this.expose_dir(EXTRA_DIR, "/srv", true); + server.expose_openapi_json(); + server.expose_dir(WEBUI_DIR, "/", false); + server.expose_dir(EXTRA_DIR, "/srv", true); for (fs_path, web_path) in EXPOSED_FILES_RW { let fs_path = FS_PREFIX.to_owned() + *fs_path; - this.expose_file_rw(fs_path, web_path); + server.expose_file_rw(fs_path, web_path)?; } - this + Ok(server) } /// Serve a compiled-in openapi.json file @@ -109,8 +110,8 @@ impl HttpServer { } /// Serve a file from disk for reading and writing - fn expose_file_rw(&mut self, fs_path: String, web_path: &str) { - self.server.at(web_path).serve_file(&fs_path).unwrap(); + fn expose_file_rw(&mut self, fs_path: String, web_path: &str) -> Result<()> { + self.server.at(web_path).serve_file(&fs_path)?; self.server .at(web_path) @@ -124,9 +125,11 @@ impl HttpServer { Ok(Response::new(204)) } }); + Ok(()) } - pub async fn serve(self) -> Result<(), std::io::Error> { - self.server.listen(self.listeners).await + pub async fn serve(self) -> Result<()> { + self.server.listen(self.listeners).await?; + Ok(()) } } diff --git a/src/led.rs b/src/led.rs index 1d76dd46..3bf532dc 100644 --- a/src/led.rs +++ b/src/led.rs @@ -17,6 +17,7 @@ use std::io::ErrorKind; +use anyhow::Result; use async_std::prelude::*; use async_std::sync::Arc; use async_std::task::spawn; @@ -91,7 +92,7 @@ fn handle_color( bb: &mut BrokerBuilder, hardware_name: &'static str, topic_name: &'static str, -) -> Arc> { +) -> Result>> { let topic = bb.topic_ro(&format!("/v1/tac/led/{topic_name}/color"), None); if let Some(led) = get_led_checked(hardware_name) { @@ -99,7 +100,7 @@ fn handle_color( spawn(async move { while let Some((r, g, b)) = rx.next().await { - let max = led.max_brightness().unwrap(); + let max = led.max_brightness()?; // I've encountered LEDs staying off when set to the max value, // but setting them to (max - 1) turned them on. @@ -109,22 +110,23 @@ fn handle_color( warn!("Failed to set LED color: {}", e); } } + anyhow::Ok(()) }); } - topic + Ok(topic) } impl Led { - pub fn new(bb: &mut BrokerBuilder) -> Self { - Self { + pub fn new(bb: &mut BrokerBuilder) -> Result { + Ok(Self { out_0: handle_pattern(bb, "tac:green:out0", "out_0"), out_1: handle_pattern(bb, "tac:green:out1", "out_1"), dut_pwr: handle_pattern(bb, "tac:green:dutpwr", "dut_pwr"), eth_dut: handle_pattern(bb, "tac:green:statusdut", "eth_dut"), eth_lab: handle_pattern(bb, "tac:green:statuslab", "eth_lab"), status: handle_pattern(bb, "rgb:status", "status"), - status_color: handle_color(bb, "rgb:status", "status"), - } + status_color: handle_color(bb, "rgb:status", "status")?, + }) } } diff --git a/src/main.rs b/src/main.rs index 0ad4f181..33d5c39f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -68,7 +68,7 @@ async fn main() -> Result<()> { // Expose hardware on the TAC via the broker framework. let backlight = Backlight::new(&mut bb)?; - let led = Led::new(&mut bb); + let led = Led::new(&mut bb)?; let adc = Adc::new(&mut bb).await?; let dut_pwr = DutPwrThread::new( &mut bb, @@ -77,7 +77,7 @@ async fn main() -> Result<()> { led.dut_pwr.clone(), ) .await?; - let dig_io = DigitalIo::new(&mut bb, led.out_0.clone(), led.out_1.clone()); + let dig_io = DigitalIo::new(&mut bb, led.out_0.clone(), led.out_1.clone())?; let regulators = Regulators::new(&mut bb); let temperatures = Temperatures::new(&mut bb); let usb_hub = UsbHub::new(&mut bb); @@ -91,7 +91,7 @@ async fn main() -> Result<()> { adc.iobus_volt.fast.clone(), ); let (network, rauc, systemd) = { - let dbus = DbusSession::new(&mut bb, led.eth_dut.clone(), led.eth_lab.clone()).await; + let dbus = DbusSession::new(&mut bb, led.eth_dut.clone(), led.eth_lab.clone()).await?; (dbus.network, dbus.rauc, dbus.systemd) }; @@ -107,7 +107,7 @@ async fn main() -> Result<()> { // Set up a http server and provide some static files like the web // interface and config files that may be edited inside the web ui. - let mut http_server = HttpServer::new(); + let mut http_server = HttpServer::new()?; // Allow editing some aspects of the TAC configuration when in "setup mode". let setup_mode = SetupMode::new(&mut bb, &mut http_server.server); diff --git a/src/measurement.rs b/src/measurement.rs index 3d403e1b..85d1c309 100644 --- a/src/measurement.rs +++ b/src/measurement.rs @@ -18,6 +18,7 @@ use std::ops::{Deref, DerefMut}; use std::time::{Instant, SystemTime}; +use anyhow::{Context, Result}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; #[derive(Debug, Clone, Copy)] @@ -57,9 +58,11 @@ impl Timestamp { /// /// The idea is to take the current Instant (monotonic time) and System Time /// (calendar time) and calculate: now_system - (now_instant - ts_instant). - pub fn in_system_time(&self) -> SystemTime { + pub fn in_system_time(&self) -> Result { let age = self.0.elapsed(); - SystemTime::now().checked_sub(age).unwrap() + SystemTime::now() + .checked_sub(age) + .with_context(|| "couldn't get system time") } } @@ -80,25 +83,33 @@ impl DerefMut for Timestamp { impl Serialize for Timestamp { /// Serialize an Instant as a javascript timestamp (f64 containing the number /// of milliseconds since Unix Epoch 0). - fn serialize(&self, serializer: S) -> Result + fn serialize(&self, serializer: S) -> std::result::Result where S: Serializer, { - let age_as_sys = self.in_system_time(); - let timestamp = age_as_sys.duration_since(SystemTime::UNIX_EPOCH).unwrap(); - let js_timestamp = 1000.0 * timestamp.as_secs_f64(); - js_timestamp.serialize(serializer) + use serde::ser::Error; + match { + || { + let time = self.in_system_time()?; + let timestamp = time.duration_since(SystemTime::UNIX_EPOCH)?; + let js_timestamp = 1000.0 * timestamp.as_secs_f64(); + anyhow::Ok(js_timestamp) + } + }() { + Ok(timestamp) => timestamp.serialize(serializer), + Err(e) => Err(Error::custom(format!( + "failed to serialize Timestamp with {e}" + ))), + } } } impl<'d> Deserialize<'d> for Timestamp { - fn deserialize(deserializer: D) -> Result + fn deserialize(_: D) -> Result where D: Deserializer<'d>, { - let _js_timestamp = f64::deserialize(deserializer)?; - // We need both Serialize and Deserialize for Topics, even when they - // are never deserialized in practice like Timestamps. - unimplemented!(); + use serde::de::Error; + Err(Error::custom("unused implementation")) } } diff --git a/src/ui.rs b/src/ui.rs index 648151b1..e6535aac 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -17,6 +17,7 @@ use std::time::Duration; +use anyhow::Result; use async_std::prelude::*; use async_std::sync::Arc; use async_std::task::spawn; @@ -176,7 +177,7 @@ impl Ui { } } - pub async fn run(mut self, display: Display) -> Result<(), std::io::Error> { + pub async fn run(mut self, display: Display) -> Result<()> { let (mut screen_rx, _) = self.screen.clone().subscribe_unbounded(); let (mut alerts_rx, _) = self.alerts.clone().subscribe_unbounded(); let (mut button_events, _) = self.buttons.clone().subscribe_unbounded(); diff --git a/src/watchdog.rs b/src/watchdog.rs index e1581234..f9ea1c6e 100644 --- a/src/watchdog.rs +++ b/src/watchdog.rs @@ -15,16 +15,17 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -use std::io::{Error, ErrorKind, Result}; +use std::io::{Error, ErrorKind}; use std::time::Duration; +use anyhow::Result; use async_std::task::sleep; use crate::dut_power::TickReader; #[cfg(any(test, feature = "demo_mode"))] mod sd { - use std::io::Result; + use anyhow::Result; pub const STATE_READY: () = (); pub const STATE_WATCHDOG: () = (); @@ -84,10 +85,9 @@ impl Watchdog { notify(false, [(STATE_WATCHDOG, "trigger")].iter())?; - break Err(Error::new( - ErrorKind::TimedOut, - "Power Thread stalled for too long", - )); + break Err( + Error::new(ErrorKind::TimedOut, "Power Thread stalled for too long").into(), + ); } notify(false, [(STATE_WATCHDOG, "1")].iter())?;