]> code.octet-stream.net Git - netwatcher/commitdiff
Improve errors
authorThomas Karpiniec <tom.karpiniec@outlook.com>
Fri, 28 Jun 2024 01:13:17 +0000 (11:13 +1000)
committerThomas Karpiniec <tom.karpiniec@outlook.com>
Fri, 28 Jun 2024 01:13:17 +0000 (11:13 +1000)
src/error.rs [new file with mode: 0644]
src/lib.rs
src/list_unix.rs
src/list_win.rs
src/watch_linux.rs

diff --git a/src/error.rs b/src/error.rs
new file mode 100644 (file)
index 0000000..bb099cc
--- /dev/null
@@ -0,0 +1,24 @@
+/// Errors in netwatcher or in one of the underlying platform integratinos.
+#[derive(Debug, Clone, PartialEq, Eq)]
+#[non_exhaustive]
+pub enum Error {
+    CreateSocket(String),
+    Bind(String),
+    CreatePipe(String),
+    Getifaddrs(String),
+    GetInterfaceName(String),
+    FormatMacAddress,
+    UnexpectedWindowsResult(u32),
+    AddressNotAssociated,
+    InvalidParameter,
+    NotEnoughMemory,
+    InvalidHandle,
+}
+
+impl std::fmt::Display for Error {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{:?}", self)
+    }
+}
+
+impl std::error::Error for Error {}
index 6d22c98d391fb37b1f241d850349f69b29ee8297..495b9e64f5098aadb9b1d7d8b8d7f4a4603f2a40 100644 (file)
@@ -4,7 +4,7 @@ use std::{
     ops::Sub,
 };
 
-use nix::errno::Errno;
+mod error;
 
 #[cfg_attr(windows, path = "list_win.rs")]
 #[cfg_attr(unix, path = "list_unix.rs")]
@@ -20,6 +20,8 @@ mod watch;
 
 type IfIndex = u32;
 
+pub use error::Error;
+
 /// Information about one network interface at a point in time.
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct Interface {
@@ -73,18 +75,6 @@ pub struct InterfaceDiff {
     pub addrs_removed: Vec<IpAddr>,
 }
 
-/// Errors in netwatcher or in one of the underlying platform integratinos.
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub enum Error {
-    CreateSocket(Errno),
-    Bind(Errno),
-    CreatePipe(Errno),
-    Getifaddrs(Errno),
-    GetInterfaceName(Errno),
-    FormatMacAddress,
-    Internal,
-}
-
 #[derive(Default, PartialEq, Eq)]
 struct List(HashMap<IfIndex, Interface>);
 
index a7cd8815553ca865ca8cfb38581e22d0d04f0a31..4a491402282893e1b7043cd05ffa1a0e640f7d05 100644 (file)
@@ -13,12 +13,12 @@ struct CandidateInterface {
 }
 
 pub(crate) fn list_interfaces() -> Result<List, Error> {
-    let addrs = getifaddrs().map_err(|e| Error::Getifaddrs(e))?;
+    let addrs = getifaddrs().map_err(|e| Error::Getifaddrs(e.to_string()))?;
     let mut candidates = HashMap::new();
 
     for addr in addrs {
-        let index =
-            if_nametoindex(addr.interface_name.as_str()).map_err(|e| Error::GetInterfaceName(e))?;
+        let index = if_nametoindex(addr.interface_name.as_str())
+            .map_err(|e| Error::GetInterfaceName(e.to_string()))?;
         let candidate = candidates
             .entry(addr.interface_name.clone())
             .or_insert_with(|| CandidateInterface {
index 8f0b7833d5d1a2a57782d55bc38f3533dd9181d6..00b776987d015cc4c599dd9379554338f43273bc 100644 (file)
@@ -38,15 +38,15 @@ pub(crate) fn list_interfaces() -> Result<List, Error> {
             );
             match WIN32_ERROR(res) {
                 ERROR_SUCCESS => break,
-                ERROR_ADDRESS_NOT_ASSOCIATED => return Err(Error::Internal),
+                ERROR_ADDRESS_NOT_ASSOCIATED => return Err(Error::AddressNotAssociated),
                 ERROR_BUFFER_OVERFLOW => {
                     buf.resize(sizepointer as usize, 0);
                     continue;
                 }
-                ERROR_INVALID_PARAMETER => return Err(Error::Internal),
-                ERROR_NOT_ENOUGH_MEMORY => return Err(Error::Internal),
+                ERROR_INVALID_PARAMETER => return Err(Error::InvalidParameter),
+                ERROR_NOT_ENOUGH_MEMORY => return Err(Error::NotEnoughMemory),
                 ERROR_NO_DATA => return Ok(List(HashMap::new())), // there aren't any
-                _ => return Err(Error::Internal), // TODO: Use FormatMessage to get a string
+                _ => return Err(Error::UnexpectedWindowsResult(res)),
             }
         }
 
@@ -61,10 +61,10 @@ pub(crate) fn list_interfaces() -> Result<List, Error> {
             let mut hw_addr = String::with_capacity(adapter.PhysicalAddressLength as usize * 3);
             for i in 0..adapter.PhysicalAddressLength as usize {
                 if i != 0 {
-                    write!(hw_addr, ":").map_err(|_| Error::Internal)?;
+                    write!(hw_addr, ":").map_err(|_| Error::FormatMacAddress)?;
                 }
                 write!(hw_addr, "{:02X}", adapter.PhysicalAddress[i])
-                    .map_err(|_| Error::Internal)?;
+                    .map_err(|_| Error::FormatMacAddress)?;
             }
             let mut ips = vec![];
             let mut unicast_ptr = adapter.FirstUnicastAddress;
index e8e1ffc6350236c4a5a3d96ea8378ea4d280f1de..c38be37df9b04dde2a42fbdc4ba1aaa91e17c2c6 100644 (file)
@@ -44,14 +44,14 @@ fn start_watcher_thread<F: FnMut(Update) + Send + 'static>(
         SockFlag::empty(),
         Some(SockProtocol::NetlinkRoute),
     )
-    .map_err(|e| Error::CreateSocket(e))?;
-    // TODO: set nonblocking
+    .map_err(|e| Error::CreateSocket(e.to_string()))?;
+    sockfd.set_nonblocking(true);
     let sa_nl = NetlinkAddr::new(
         0,
         (RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR) as u32,
     );
-    bind(sockfd.as_raw_fd(), &sa_nl).map_err(|e| Error::Bind(e))?;
-    let (pipe_rd, pipe_wr) = pipe().map_err(|e| Error::CreatePipe(e))?;
+    bind(sockfd.as_raw_fd(), &sa_nl).map_err(|e| Error::Bind(e.to_string()))?;
+    let (pipe_rd, pipe_wr) = pipe().map_err(|e| Error::CreatePipe(e.to_string()))?;
 
     let mut prev_list = List::default();
     let mut handle_update = move |new_list: List| {