//! Custom error type for `peach-network`. use std::io; use std::num::ParseIntError; use io::Error as IoError; use probes::ProbeError; use regex::Error as RegexError; use wpactrl::WpaError; /// Custom error type encapsulating all possible errors when querying /// network interfaces and modifying their state. #[derive(Debug)] pub enum NetworkError { /// Failed to add network. Add { /// SSID. ssid: String, }, /// Failed to retrieve network state. NoState { /// Interface. iface: String, /// Underlying error source. source: IoError, }, /// Failed to disable network. Disable { /// ID. id: String, /// Interface. iface: String, }, /// Failed to disconnect interface. Disconnect { /// Interface. iface: String, }, /// Failed to execute wpa_passphrase command. GenWpaPassphrase { /// SSID. ssid: String, /// Underlying error source. source: IoError, }, /// Failed to successfully generate wpa passphrase. GenWpaPassphraseWarning { /// SSID. ssid: String, /// Error message describing context. err_msg: String, }, /// Failed to retrieve ID for the given SSID and interface. Id { /// SSID. ssid: String, /// Interface. iface: String, }, /// Failed to retrieve IP address. NoIp { /// Inteface. iface: String, /// Underlying error source. source: IoError, }, /// Failed to retrieve RSSI. Rssi { /// Interface. iface: String, }, /// Failed to retrieve signal quality (%). RssiPercent { /// Interface. iface: String, }, /// Failed to retrieve SSID. Ssid { /// Interface. iface: String, }, /// Failed to retrieve state. State { /// Interface. iface: String, }, /// Failed to retrieve status. Status { /// Interface. iface: String, }, /// Failed to retieve network traffic. Traffic { /// Interface. iface: String, }, /// No saved network found for the default interface. SavedNetworks, /// No networks found in range. AvailableNetworks { /// Interface. iface: String, }, /// Failed to set new password. Modify { /// ID. id: String, /// Interface. iface: String, }, /// Failed to retrieve IP address. Ip { /// Interface. iface: String, }, /// Failed to parse integer from string. ParseInt(ParseIntError), /// Failed to retrieve network traffic measurement. NoTraffic { /// Interface. iface: String, /// Underlying error source. source: ProbeError, }, /// Failed to reassociate with WiFi network. Reassociate { /// Interface. iface: String, }, /// Failed to force reread of wpa_supplicant configuration file. Reconfigure, /// Failed to reconnect with WiFi network. Reconnect { /// Interface. iface: String, }, /// Failed to execute Regex command. Regex(RegexError), /// Failed to delete network. Delete { /// ID. id: String, /// Interface. iface: String, }, /// Failed to retrieve state of wlan0 service. WlanState(IoError), /// Failed to retrieve connection state of wlan0 interface. WlanOperstate(IoError), /// Failed to save wpa_supplicant configuration changes to file. Save, /// Failed to connect to network. Connect { /// ID. id: String, /// Interface. iface: String, }, /// Failed to start systemctl service for a network interface. StartInterface { /// Underlying error source. source: IoError, /// Interface. iface: String, }, /// Failed to execute wpa-ctrl command. WpaCtrl(WpaError), } impl std::error::Error for NetworkError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match *self { NetworkError::Add { .. } => None, NetworkError::NoState { ref source, .. } => Some(source), NetworkError::Disable { .. } => None, NetworkError::Disconnect { .. } => None, NetworkError::GenWpaPassphrase { ref source, .. } => Some(source), NetworkError::GenWpaPassphraseWarning { .. } => None, NetworkError::Id { .. } => None, NetworkError::NoIp { ref source, .. } => Some(source), NetworkError::Rssi { .. } => None, NetworkError::RssiPercent { .. } => None, NetworkError::Ssid { .. } => None, NetworkError::State { .. } => None, NetworkError::Status { .. } => None, NetworkError::Traffic { .. } => None, NetworkError::SavedNetworks => None, NetworkError::AvailableNetworks { .. } => None, NetworkError::Modify { .. } => None, NetworkError::Ip { .. } => None, NetworkError::ParseInt(ref source) => Some(source), NetworkError::NoTraffic { ref source, .. } => Some(source), NetworkError::Reassociate { .. } => None, NetworkError::Reconfigure { .. } => None, NetworkError::Reconnect { .. } => None, NetworkError::Regex(ref source) => Some(source), NetworkError::Delete { .. } => None, NetworkError::WlanState(ref source) => Some(source), NetworkError::WlanOperstate(ref source) => Some(source), NetworkError::Save => None, NetworkError::Connect { .. } => None, NetworkError::StartInterface { ref source, .. } => Some(source), NetworkError::WpaCtrl(ref source) => Some(source), } } } impl std::fmt::Display for NetworkError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match *self { NetworkError::Add { ref ssid } => { write!(f, "Failed to add network for {}", ssid) } NetworkError::NoState { ref iface, .. } => { write!(f, "Failed to retrieve state for interface: {}", iface) } NetworkError::Disable { ref id, ref iface } => { write!( f, "Failed to disable network {} for interface: {}", id, iface ) } NetworkError::Disconnect { ref iface } => { write!(f, "Failed to disconnect {}", iface) } NetworkError::GenWpaPassphrase { ref ssid, .. } => { write!(f, "Failed to generate wpa passphrase for {}", ssid) } NetworkError::GenWpaPassphraseWarning { ref ssid, ref err_msg, } => { write!( f, "Failed to generate wpa passphrase for {}: {}", ssid, err_msg ) } NetworkError::Id { ref ssid, ref iface, } => { write!(f, "No ID found for {} on interface: {}", ssid, iface) } NetworkError::NoIp { ref iface, .. } => { write!(f, "Could not access IP address for interface: {}", iface) } NetworkError::Rssi { ref iface } => { write!(f, "Could not find RSSI for interface: {}", iface) } NetworkError::RssiPercent { ref iface } => { write!( f, "Could not find signal quality (%) for interface: {}", iface ) } NetworkError::Ssid { ref iface } => { write!(f, "Could not find SSID for interface: {}", iface) } NetworkError::State { ref iface } => { write!(f, "No state found for interface: {}", iface) } NetworkError::Status { ref iface } => { write!(f, "No status found for interface: {}", iface) } NetworkError::Traffic { ref iface } => { write!(f, "Could not find network traffic for interface: {}", iface) } NetworkError::SavedNetworks => { write!(f, "No saved networks found for default interface") } NetworkError::AvailableNetworks { ref iface } => { write!(f, "No networks found in range of interface: {}", iface) } NetworkError::Modify { ref id, ref iface } => { write!( f, "Failed to set new password for network {} on {}", id, iface ) } NetworkError::Ip { ref iface } => { write!(f, "No IP found for interface: {}", iface) } NetworkError::ParseInt(_) => { write!(f, "Failed to parse integer from string for RSSI value") } NetworkError::NoTraffic { ref iface, .. } => { write!( f, "Failed to retrieve network traffic measurement for {}", iface ) } NetworkError::Reassociate { ref iface } => { write!( f, "Failed to reassociate with WiFi network for interface: {}", iface ) } NetworkError::Reconfigure => { write!( f, "Failed to force reread of wpa_supplicant configuration file" ) } NetworkError::Reconnect { ref iface } => { write!( f, "Failed to reconnect with WiFi network for interface: {}", iface ) } NetworkError::Regex(_) => write!(f, "Regex command failed"), NetworkError::Delete { ref id, ref iface } => { write!( f, "Failed to delete network {} for interface: {}", id, iface ) } NetworkError::WlanState(_) => write!(f, "Failed to retrieve state of wlan0 service"), NetworkError::WlanOperstate(_) => { write!(f, "Failed to retrieve connection state of wlan0 interface") } NetworkError::Save => write!(f, "Failed to save configuration changes to file"), NetworkError::Connect { ref id, ref iface } => { write!( f, "Failed to connect to network {} for interface: {}", id, iface ) } NetworkError::StartInterface { ref iface, .. } => write!( f, "Failed to start systemctl service for {} interface", iface ), NetworkError::WpaCtrl(_) => write!(f, "WpaCtrl command failed"), } } } impl From for NetworkError { fn from(err: WpaError) -> Self { NetworkError::WpaCtrl(err) } } impl From for NetworkError { fn from(err: ParseIntError) -> Self { NetworkError::ParseInt(err) } } impl From for NetworkError { fn from(err: RegexError) -> Self { NetworkError::Regex(err) } }