From bb3892a239412d95b954adb795407d6d0a244f07 Mon Sep 17 00:00:00 2001 From: Avii Date: Thu, 26 Feb 2026 20:35:04 +0100 Subject: [PATCH] Error Handling --- src/lib.rs | 60 +++++++++++++++++++++---------------- src/main.rs | 2 +- src/messages/device_info.rs | 4 +-- src/messages/header.rs | 4 +-- src/messages/hello.rs | 18 ++++++----- src/messages/mod.rs | 9 ++++-- src/messages/ping.rs | 4 +-- src/messages/state.rs | 4 +-- 8 files changed, 60 insertions(+), 45 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 26792f9..8ceaa44 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,43 +30,53 @@ impl OtdIpc { 1, )?; - stream.write_all(&Vec::from(hello))?; + stream.write_all(&Vec::try_from(hello)?)?; Ok(Self { stream }) } } impl Iterator for OtdIpc { - type Item = Message; + type Item = Result>; fn next(&mut self) -> Option { let mut raw_header = [0; size_of::
()]; - self.stream.read_exact(&mut raw_header).unwrap(); + if let Err(e) = self.stream.read_exact(&mut raw_header) { + return Some(Err(e.into())); + }; + + let header: Header = match raw_header[..].try_into() { + Ok(e) => e, + Err(e) => return Some(Err(e)), + }; - let header: Header = raw_header[..].try_into().unwrap(); let mut raw_buffer = vec![0; (header.size as usize) - size_of::
()]; - self.stream.read_exact(&mut raw_buffer).unwrap(); - match header.message_type { - messages::MessageType::None => None, - messages::MessageType::DeviceInfo => Some(Message::DeviceInfo(Box::new( - DeviceInfo::try_from(&raw_buffer[..]).unwrap(), - ))), - messages::MessageType::State => { - Some(Message::State(State::try_from(&raw_buffer[..]).unwrap())) - } - messages::MessageType::Ping => { - Some(Message::Ping(Ping::try_from(&raw_buffer[..]).unwrap())) - } - messages::MessageType::DebugMessage => { - Some(Message::DebugMessage(DebugMessage::from(&raw_buffer[..]))) - } - messages::MessageType::Experimental => { - Some(Message::Experimental(Experimental::from(&raw_buffer[..]))) - } - messages::MessageType::Hello => { - Some(Message::Hello(Hello::try_from(&raw_buffer[..]).unwrap())) - } + if let Err(e) = self.stream.read_exact(&mut raw_buffer) { + return Some(Err(e.into())); } + + Some(get_message(header.message_type, &raw_buffer)) } } + +fn get_message( + message_type: MessageType, + raw_buffer: &[u8], +) -> Result> { + Ok(match message_type { + messages::MessageType::None => Message::None, + messages::MessageType::DeviceInfo => { + Message::DeviceInfo(Box::new(DeviceInfo::try_from(raw_buffer)?)) + } + messages::MessageType::State => Message::State(State::try_from(raw_buffer)?), + messages::MessageType::Ping => Message::Ping(Ping::try_from(raw_buffer)?), + messages::MessageType::DebugMessage => { + Message::DebugMessage(DebugMessage::from(raw_buffer)) + } + messages::MessageType::Experimental => { + Message::Experimental(Experimental::from(raw_buffer)) + } + messages::MessageType::Hello => Message::Hello(Hello::try_from(raw_buffer)?), + }) +} diff --git a/src/main.rs b/src/main.rs index 19366d4..79905ba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,7 @@ fn main() -> Result<(), Box> { let otd_ipc = OtdIpc::new("otd-ipc-rs", "master")?; for msg in otd_ipc { - dbg!(msg); + dbg!(msg?); } Ok(()) diff --git a/src/messages/device_info.rs b/src/messages/device_info.rs index e248a71..bced22d 100644 --- a/src/messages/device_info.rs +++ b/src/messages/device_info.rs @@ -13,11 +13,11 @@ pub struct DeviceInfo { } impl TryFrom<&[u8]> for DeviceInfo { - type Error = &'static str; + type Error = Box; fn try_from(mut bytes: &[u8]) -> Result { if bytes.len() < 12 + 256 + 256 { - return Err("buffer too small"); + return Err("buffer too small".into()); } let max_x = f32::from_le_bytes(take::<4>(&mut bytes)?); diff --git a/src/messages/header.rs b/src/messages/header.rs index 925946b..d75d0c9 100644 --- a/src/messages/header.rs +++ b/src/messages/header.rs @@ -12,11 +12,11 @@ pub struct Header { } impl TryFrom<&[u8]> for Header { - type Error = &'static str; + type Error = Box; fn try_from(mut bytes: &[u8]) -> Result { if bytes.len() < 12 { - return Err("buffer too small"); + return Err("buffer too small".into()); } Ok(Self { diff --git a/src/messages/hello.rs b/src/messages/hello.rs index 08ddcba..50e8e89 100644 --- a/src/messages/hello.rs +++ b/src/messages/hello.rs @@ -45,8 +45,10 @@ impl Hello { } } -impl From for Vec { - fn from(value: Hello) -> Self { +impl TryFrom for Vec { + type Error = Box; + + fn try_from(value: Hello) -> Result { let mut output = Vec::with_capacity(std::mem::size_of::()); // Header @@ -56,22 +58,22 @@ impl From for Vec { // Hello output.extend_from_slice(&value.protocol_version.to_le_bytes()); - output.extend_from_slice(&str_to_fixed(&value.human_readable_name).unwrap()); - output.extend_from_slice(&str_to_fixed(&value.human_readable_version).unwrap()); - output.extend_from_slice(&str_to_fixed(&value.implementation_id).unwrap()); + output.extend_from_slice(&str_to_fixed(&value.human_readable_name)?); + output.extend_from_slice(&str_to_fixed(&value.human_readable_version)?); + output.extend_from_slice(&str_to_fixed(&value.implementation_id)?); output.push(value.compatibility_version); - output + Ok(output) } } impl TryFrom<&[u8]> for Hello { - type Error = &'static str; + type Error = Box; fn try_from(mut bytes: &[u8]) -> Result { if bytes.len() < 8 + 256 + 256 + 256 + 1 { - return Err("buffer too small"); + return Err("buffer too small".into()); } // random 4 bytes are here now, wtf? diff --git a/src/messages/mod.rs b/src/messages/mod.rs index 2365f50..70cbee1 100644 --- a/src/messages/mod.rs +++ b/src/messages/mod.rs @@ -18,6 +18,7 @@ pub use state::*; #[derive(Debug, Clone)] pub enum Message { + None, DeviceInfo(Box), State(State), Ping(Ping), @@ -27,11 +28,13 @@ pub enum Message { } // helper to read fixed-size chunks -pub(super) fn take(bytes: &mut &[u8]) -> Result<[u8; N], &'static str> { +pub(super) fn take( + bytes: &mut &[u8], +) -> Result<[u8; N], Box> { if bytes.len() < N { - return Err("buffer too small"); + return Err("buffer too small".into()); } let (head, tail) = bytes.split_at(N); *bytes = tail; - Ok(head.try_into().unwrap()) + Ok(head.try_into()?) } diff --git a/src/messages/ping.rs b/src/messages/ping.rs index 8be1bd8..3b23919 100644 --- a/src/messages/ping.rs +++ b/src/messages/ping.rs @@ -10,11 +10,11 @@ pub struct Ping { } impl TryFrom<&[u8]> for Ping { - type Error = &'static str; + type Error = Box; fn try_from(mut bytes: &[u8]) -> Result { if bytes.len() < 4 { - return Err("buffer too small"); + return Err("buffer too small".into()); } Ok(Self { diff --git a/src/messages/state.rs b/src/messages/state.rs index e9495c3..be5eefb 100644 --- a/src/messages/state.rs +++ b/src/messages/state.rs @@ -131,11 +131,11 @@ impl State { } impl TryFrom<&[u8]> for State { - type Error = &'static str; + type Error = Box; fn try_from(mut bytes: &[u8]) -> Result { if bytes.len() < 29 { - return Err("buffer too small"); + return Err("buffer too small".into()); } Ok(Self {