r_lanlib/
error.rs

1//! Custom Error and Result types for this library
2
3use std::{
4    any::Any,
5    num::ParseIntError,
6    sync::{
7        MutexGuard, PoisonError,
8        mpsc::{RecvError, SendError},
9    },
10};
11use thiserror::Error;
12
13use crate::{
14    packet::{
15        Reader, Sender, arp_packet::ArpPacketBuilderError,
16        heartbeat_packet::HeartbeatPacketBuilderError, rst_packet::RstPacketBuilderError,
17        syn_packet::SynPacketBuilderError,
18    },
19    scanners::ScanMessage,
20};
21
22/// Custom Error type for this library
23#[derive(Error, Debug)]
24pub enum RLanLibError {
25    /// Error coming directly off the wire
26    #[error("wire error: {_0}")]
27    Wire(String),
28
29    /// Errors resulting from events channel
30    #[error("failed to send notification message: {:#?}", _0)]
31    NotifierSendError(#[from] SendError<Box<ScanMessage>>),
32
33    /// Error obtaining lock on packet reader
34    #[error("failed to get lock on packet reader: {_0}")]
35    PacketReaderLock(String),
36
37    /// Error obtaining lock on packet sender
38    #[error("failed to get lock on packet sender: {_0}")]
39    PacketSenderLock(String),
40
41    /// Generic thread error
42    #[error("thread error: {_0}")]
43    ThreadError(String),
44
45    /// Errors when consuming messages from channels
46    #[error("failed to receive message from channel: {:#?}", _0)]
47    ChannelReceive(#[from] RecvError),
48
49    /// Error generated during ARP packet construction
50    #[error("failed to build ARP packet: {_0}")]
51    ArpPacketBuild(#[from] ArpPacketBuilderError),
52
53    /// Error generated during RST packet construction
54    #[error("failed to build RST packet: {_0}")]
55    RstPacketBuild(#[from] RstPacketBuilderError),
56
57    /// Error generated during SYN packet construction
58    #[error("failed to build SYN packet: {_0}")]
59    SynPacketBuild(#[from] SynPacketBuilderError),
60
61    /// Error generated during heartbeat packet construction
62    #[error("failed to build heartbeat packet: {_0}")]
63    HeartbeatPacketBuild(#[from] HeartbeatPacketBuilderError),
64
65    /// Wrapping errors related to scanning
66    #[error("scanning error: {error} - ip: {:#?}, port: {:#?}", ip, port)]
67    Scan {
68        /// The error message encountered
69        error: String,
70        /// The associated IP address being scanned
71        ip: Option<String>,
72        /// The associated port being scanned
73        port: Option<String>,
74    },
75}
76
77impl From<Box<dyn Any + Send>> for RLanLibError {
78    fn from(value: Box<dyn Any + Send>) -> Self {
79        if let Some(s) = value.downcast_ref::<&'static str>() {
80            Self::ThreadError(format!("Thread panicked with: {}", s))
81        } else if let Some(s) = value.downcast_ref::<String>() {
82            Self::ThreadError(format!("Thread panicked with: {}", s))
83        } else {
84            Self::ThreadError("Thread panicked with an unknown type".into())
85        }
86    }
87}
88
89impl<'a> From<PoisonError<MutexGuard<'a, dyn Reader + 'static>>> for RLanLibError {
90    fn from(value: PoisonError<MutexGuard<'a, dyn Reader + 'static>>) -> Self {
91        Self::PacketReaderLock(value.to_string())
92    }
93}
94
95impl<'a> From<PoisonError<MutexGuard<'a, dyn Sender + 'static>>> for RLanLibError {
96    fn from(value: PoisonError<MutexGuard<'a, dyn Sender + 'static>>) -> Self {
97        Self::PacketSenderLock(value.to_string())
98    }
99}
100
101impl RLanLibError {
102    /// Converter for std::net::AddrParseError
103    pub fn from_net_addr_parse_error(ip: &str, error: std::net::AddrParseError) -> Self {
104        Self::Scan {
105            error: error.to_string(),
106            ip: Some(ip.to_string()),
107            port: None,
108        }
109    }
110
111    /// Converter for ipnet::AddrParseError
112    pub fn from_ipnet_addr_parse_error(ip: &str, error: ipnet::AddrParseError) -> Self {
113        Self::Scan {
114            error: error.to_string(),
115            ip: Some(ip.to_string()),
116            port: None,
117        }
118    }
119
120    /// Converter for ParseIntError
121    pub fn from_port_parse_int_err(port: &str, error: ParseIntError) -> Self {
122        Self::Scan {
123            error: error.to_string(),
124            ip: None,
125            port: Some(port.to_string()),
126        }
127    }
128
129    /// Converter for channel send errors
130    pub fn from_channel_send_error(e: SendError<ScanMessage>) -> Self {
131        RLanLibError::NotifierSendError(SendError(Box::from(e.0)))
132    }
133}
134
135unsafe impl Send for RLanLibError {}
136unsafe impl Sync for RLanLibError {}
137
138/// Custom Result type for this library. All Errors exposed by this library
139/// will be returned as [`RLanLibError`]
140pub type Result<T> = std::result::Result<T, RLanLibError>;