Manage error in ice::get_users(..)
authorGreg Burri <greg.burri@gmail.com>
Fri, 21 Jun 2024 09:33:43 +0000 (11:33 +0200)
committerGreg Burri <greg.burri@gmail.com>
Fri, 21 Jun 2024 09:33:43 +0000 (11:33 +0200)
Cargo.lock
Cargo.toml
src/ice.rs
src/main.rs

index 3a5ea2d..8b1d9da 100644 (file)
@@ -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",
index 6616b52..c759bdb 100644 (file)
@@ -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",
index 2a791d2..29a6ac3 100644 (file)
@@ -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<User> {
+    pub fn get_users(&mut self) -> Result<Vec<User>> {
         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)
         }
     }
 }
index 075f57f..871ebd2 100644 (file)
@@ -120,31 +120,38 @@ async fn main() {
 }
 
 async fn root(State(ice): State<Arc<Mutex<ice::Ice>>>) -> impl IntoResponse {
-    let users = ice.lock().unwrap().get_users();
-
-    let mut channels = Vec::<Channel>::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::<Channel>::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() {