From c7de2b20db67e39362be92b0100300b44dda961a Mon Sep 17 00:00:00 2001 From: Greg Burri Date: Fri, 21 Jun 2024 11:33:43 +0200 Subject: [PATCH] Manage error in ice::get_users(..) --- Cargo.lock | 15 +++++++++++---- Cargo.toml | 5 +++-- src/ice.rs | 46 +++++++++++++++++++++++++++++----------------- src/main.rs | 49 ++++++++++++++++++++++++++++--------------------- 4 files changed, 71 insertions(+), 44 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3a5ea2d..8b1d9da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,6 +26,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "anyhow" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + [[package]] name = "askama" version = "0.12.1" @@ -581,6 +587,7 @@ dependencies = [ name = "mumble_web" version = "0.1.0" dependencies = [ + "anyhow", "askama", "askama_axum", "axum", @@ -721,9 +728,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "proc-macro2" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -953,9 +960,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.66" +version = "2.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "ff8655ed1d86f3af4ee3fd3263786bc14245ad17c4c7e85ba7187fb3ae028c90" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 6616b52..c759bdb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,9 @@ version = "0.1.0" edition = "2021" [dependencies] +anyhow = "1.0" +itertools = "0.13" + axum = { version = "0.7", features = ["http2"] } tokio = { version = "1", features = ["full"] } tower = { version = "0.4", features = ["util"] } @@ -17,8 +20,6 @@ ron = "0.8" # Rust object notation, to lo serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -itertools = "0.13" - askama = { version = "0.12", features = [ "with-axum", "mime", diff --git a/src/ice.rs b/src/ice.rs index 2a791d2..29a6ac3 100644 --- a/src/ice.rs +++ b/src/ice.rs @@ -11,6 +11,7 @@ use std::{ time::{self, Duration}, }; +use anyhow::{Context, Result}; use itertools::Itertools; use json::{self, JsonValue}; use rsevents::{AutoResetEvent, Awaitable, EventState}; @@ -108,24 +109,24 @@ impl Ice { ice } - pub fn get_users(&mut self) -> Vec { + pub fn get_users(&mut self) -> Result> { let now = time::Instant::now(); if self.cached_users_timestamp + CACHED_VALUES_DURATION > now { - self.cached_users.clone() + Ok(self.cached_users.clone()) } else { - let mut stream = TcpStream::connect("127.0.0.1:4978").unwrap(); + let mut stream = TcpStream::connect("127.0.0.1:4978")?; let id: u32 = 1; let length: u32 = 0; let mut buffer = [0u8; 8]; buffer[0..4].copy_from_slice(&id.to_ne_bytes()); buffer[4..8].copy_from_slice(&length.to_ne_bytes()); - stream.write(&buffer).unwrap(); + stream.write(&buffer)?; let mut id_bytes = [0u8; 4]; let mut length_bytes = [0u8; 4]; - stream.read(&mut id_bytes).unwrap(); - stream.read(&mut length_bytes).unwrap(); + stream.read(&mut id_bytes)?; + stream.read(&mut length_bytes)?; let id = u32::from_ne_bytes(id_bytes); // Response id must be 2. @@ -135,9 +136,9 @@ impl Ice { let length = u32::from_ne_bytes(length_bytes); let mut payload = vec![0u8; length as usize]; - stream.read_exact(&mut payload).unwrap(); - let json_str = from_utf8(&payload).unwrap(); - let json = json::parse(json_str).unwrap(); + stream.read_exact(&mut payload)?; + let json_str = from_utf8(&payload)?; + let json = json::parse(json_str)?; // println!("id: {}, length: {}, json: {:?}", id, length, json); // Debug. @@ -146,17 +147,28 @@ impl Ice { let user_json = &json[i]; users.push(User { - name: user_json["username"].as_str().unwrap().to_string(), - channel_path: user_json["channelPath"].as_str().unwrap().to_string(), + name: user_json["username"] + .as_str() + .context("JSON: username field missing")? + .to_string(), + channel_path: user_json["channelPath"] + .as_str() + .context("JSON: username field missing")? + .to_string(), // TODO: a bit ugly. channel_path_positions: match &user_json["channelPathPositions"] { - JsonValue::Array(array) => { - array.iter().map(|v| v.as_i32().unwrap()).collect_vec() - } + JsonValue::Array(array) => array + .iter() + .map(|v| v.as_i32().unwrap_or_default()) + .collect_vec(), _ => vec![], }, - self_mute: user_json["selfMute"].as_bool().unwrap(), - self_deaf: user_json["selfDeaf"].as_bool().unwrap(), + self_mute: user_json["selfMute"] + .as_bool() + .context("JSON: selfMute field missing")?, + self_deaf: user_json["selfDeaf"] + .as_bool() + .context("JSON: selfMute field missing")?, }); } @@ -164,7 +176,7 @@ impl Ice { self.cached_users = users.clone(); self.cached_users_timestamp = time::Instant::now(); - users + Ok(users) } } } diff --git a/src/main.rs b/src/main.rs index 075f57f..871ebd2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -120,31 +120,38 @@ async fn main() { } async fn root(State(ice): State>>) -> impl IntoResponse { - let users = ice.lock().unwrap().get_users(); - - let mut channels = Vec::::new(); - 'next_user: for u in &users { - for c in &mut channels { - if c.path == u.channel_path { - c.users.push(User::from_ice_user(u)); - continue 'next_user; + match ice.lock() { + Ok(mut ice) => { + let users = match ice.get_users() { + Ok(user) => user, + Err(err) => return err.to_string().into_response(), + }; + let mut channels = Vec::::new(); + 'next_user: for u in &users { + for c in &mut channels { + if c.path == u.channel_path { + c.users.push(User::from_ice_user(u)); + continue 'next_user; + } + } + let channel = Channel { + path: u.channel_path.clone(), + positions: u.channel_path_positions.clone(), + users: vec![User::from_ice_user(u)], + }; + channels.push(channel); } - } - let channel = Channel { - path: u.channel_path.clone(), - positions: u.channel_path_positions.clone(), - users: vec![User::from_ice_user(u)], - }; - channels.push(channel); - } - for c in &mut channels { - c.users.sort(); - } + for c in &mut channels { + c.users.sort(); + } - channels.sort(); + channels.sort(); - MainTemplate { channels } + MainTemplate { channels }.into_response() + } + Err(err) => err.to_string().into_response(), + } } async fn shutdown_signal() { -- 2.45.2