From 54985e8670be6428a05a7c2b37c49bc584084398 Mon Sep 17 00:00:00 2001 From: Andreas Neuhaus Date: Sat, 21 Dec 2024 11:23:14 +0100 Subject: [PATCH] Add telemetry tracking of errors --- firmware/src/error.rs | 1 - firmware/src/main.rs | 4 ++-- firmware/src/telemetry.rs | 15 +++++++++++---- firmware/src/ui.rs | 6 ++++-- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/firmware/src/error.rs b/firmware/src/error.rs index 3fbbb88..9f22044 100644 --- a/firmware/src/error.rs +++ b/firmware/src/error.rs @@ -32,7 +32,6 @@ impl fmt::Display for Error { impl Error { /// Error kind - #[allow(dead_code)] pub fn kind(&self) -> &ErrorKind { &self.kind } diff --git a/firmware/src/main.rs b/firmware/src/main.rs index 9524eea..654f137 100644 --- a/firmware/src/main.rs +++ b/firmware/src/main.rs @@ -255,7 +255,7 @@ async fn main(spawner: Spawner) { // Display error to user and try again Err(err) => { error!("Initialization error: {:?}", err); - let _ = ui.show_error(&err).await; + let _ = ui.show_error(err).await; } } } @@ -273,7 +273,7 @@ async fn main(spawner: Spawner) { // Display error to user and start over again Err(err) => { error!("Error: {:?}", err); - let _ = ui.show_error(&err).await; + let _ = ui.show_error(err).await; } } } diff --git a/firmware/src/telemetry.rs b/firmware/src/telemetry.rs index 410e92e..ecb1591 100644 --- a/firmware/src/telemetry.rs +++ b/firmware/src/telemetry.rs @@ -1,6 +1,6 @@ use crate::http::Http; use crate::mixpanel::{self, Mixpanel}; -use crate::{article, json, nfc, user}; +use crate::{article, error, json, nfc, user}; use alloc::collections::VecDeque; use embassy_time::{Duration, Instant}; use embedded_io_async::Write; @@ -28,6 +28,8 @@ pub enum Event { UserAuthenticated(user::UserId, nfc::Uid), /// Article purchased (user id, article id, amount, total price) ArticlePurchased(user::UserId, article::ArticleId, f32, f32), + /// Error occured + Error(error::Error), } impl Event { @@ -39,18 +41,20 @@ impl Event { Event::AuthenticationFailed(..) => "authentication_failed", Event::UserAuthenticated(..) => "user_authenticated", Event::ArticlePurchased(..) => "article_purchased", + Event::Error(..) => "error", } } /// User id associated with this event, if any - pub fn user_id(&self) -> Option<&user::UserId> { + pub fn user_id(&self) -> Option { #[allow(clippy::match_same_arms)] match self { Event::SystemStart => None, Event::DataRefreshed(..) => None, Event::AuthenticationFailed(..) => None, - Event::UserAuthenticated(user_id, ..) => Some(user_id), - Event::ArticlePurchased(user_id, ..) => Some(user_id), + Event::UserAuthenticated(user_id, ..) => Some(*user_id), + Event::ArticlePurchased(user_id, ..) => Some(*user_id), + Event::Error(err) => err.user_id(), } } @@ -85,6 +89,9 @@ impl Event { .field("total_price", total_price) .await?; } + Event::Error(err) => { + object.field("error_message", err.kind()).await?; + } } Ok(()) } diff --git a/firmware/src/ui.rs b/firmware/src/ui.rs index 80b53f9..ee9ff5d 100644 --- a/firmware/src/ui.rs +++ b/firmware/src/ui.rs @@ -106,16 +106,18 @@ impl<'a, RNG: RngCore, I2C: I2c, IRQ: Wait> Ui<'a, RNG, I2C, } /// Show error screen and wait for keypress or timeout - pub async fn show_error(&mut self, error: &Error) -> Result<(), Error> { + pub async fn show_error(&mut self, error: Error) -> Result<(), Error> { info!("UI: Displaying error: {}", error); - self.display.screen(&screen::Failure::new(error)).await?; + self.display.screen(&screen::Failure::new(&error)).await?; // Sound the error buzzer if the error was caused by a user's interaction if error.user_id().is_some() { let _ = self.buzzer.error().await; } + self.telemetry.track(Event::Error(error)); + // Wait at least 1s without responding to keypad let min_time = Duration::from_secs(1); Timer::after(min_time).await;