nmrs 2.3.0

A Rust library for NetworkManager over D-Bus
Documentation
use thiserror::Error;

use super::connection_state::ConnectionStateReason;
use super::state_reason::StateReason;

/// Errors that can occur during network operations.
///
/// This enum provides specific error types for different failure modes,
/// making it easy to handle errors appropriately in your application.
///
/// # Examples
///
/// ## Basic Error Handling
///
/// ```no_run
/// use nmrs::{NetworkManager, WifiSecurity, ConnectionError};
///
/// # async fn example() -> nmrs::Result<()> {
/// let nm = NetworkManager::new().await?;
///
/// match nm.connect("MyNetwork", WifiSecurity::WpaPsk {
///     psk: "password".into()
/// }).await {
///     Ok(_) => println!("Connected!"),
///     Err(ConnectionError::AuthFailed) => {
///         eprintln!("Wrong password");
///     }
///     Err(ConnectionError::NotFound) => {
///         eprintln!("Network not in range");
///     }
///     Err(ConnectionError::Timeout) => {
///         eprintln!("Connection timed out");
///     }
///     Err(e) => eprintln!("Error: {}", e),
/// }
/// # Ok(())
/// # }
/// ```
///
/// ## Retry Logic
///
/// ```no_run
/// use nmrs::{NetworkManager, WifiSecurity, ConnectionError};
///
/// # async fn example() -> nmrs::Result<()> {
/// let nm = NetworkManager::new().await?;
///
/// for attempt in 1..=3 {
///     match nm.connect("MyNetwork", WifiSecurity::Open).await {
///         Ok(_) => {
///             println!("Connected on attempt {}", attempt);
///             break;
///         }
///         Err(ConnectionError::Timeout) if attempt < 3 => {
///             println!("Timeout, retrying...");
///             continue;
///         }
///         Err(e) => return Err(e),
///     }
/// }
/// # Ok(())
/// # }
/// ```
#[non_exhaustive]
#[derive(Debug, Error)]
pub enum ConnectionError {
    /// A D-Bus communication error occurred.
    #[error("D-Bus error: {0}")]
    Dbus(#[from] zbus::Error),

    /// The requested network was not found during scan.
    #[error("network not found")]
    NotFound,

    /// Authentication with the access point failed (wrong password, rejected credentials).
    #[error("authentication failed")]
    AuthFailed,

    /// The supplicant (wpa_supplicant) encountered a configuration error.
    #[error("supplicant configuration failed")]
    SupplicantConfigFailed,

    /// The supplicant timed out during authentication.
    #[error("supplicant timeout")]
    SupplicantTimeout,

    /// DHCP failed to obtain an IP address.
    #[error("DHCP failed")]
    DhcpFailed,

    /// The connection timed out waiting for activation.
    #[error("connection timeout")]
    Timeout,

    /// The connection is stuck in an unexpected state.
    #[error("connection stuck in state: {0}")]
    Stuck(String),

    /// No Wi-Fi device was found on the system.
    #[error("no Wi-Fi device found")]
    NoWifiDevice,

    /// No wired (ethernet) device was found on the system.
    #[error("no wired device was found")]
    NoWiredDevice,

    /// Wi-Fi device did not become ready in time.
    #[error("Wi-Fi device not ready")]
    WifiNotReady,

    /// No saved connection exists for the requested network.
    #[error("no saved connection for network")]
    NoSavedConnection,

    /// An empty password was provided for the requested network.
    #[error("no password was provided")]
    MissingPassword,

    /// A general connection failure with a device state reason code.
    #[error("connection failed: {0}")]
    DeviceFailed(StateReason),

    /// A connection activation failure with a connection state reason.
    #[error("connection activation failed: {0}")]
    ActivationFailed(ConnectionStateReason),

    /// Invalid UTF-8 encountered in SSID.
    #[error("invalid UTF-8 in SSID: {0}")]
    InvalidUtf8(#[from] std::str::Utf8Error),

    /// No VPN connection found
    #[error("no VPN connection found")]
    NoVpnConnection,

    /// Invalid IP address or CIDR notation
    #[error("invalid address: {0}")]
    InvalidAddress(String),

    /// Invalid VPN peer configuration
    #[error("invalid peer configuration: {0}")]
    InvalidPeers(String),

    /// Invalid WireGuard private key format
    #[error("invalid WireGuard private key: {0}")]
    InvalidPrivateKey(String),

    /// Invalid WireGuard public key format
    #[error("invalid WireGuard public key: {0}")]
    InvalidPublicKey(String),

    /// Invalid VPN gateway format (should be host:port)
    #[error("invalid VPN gateway: {0}")]
    InvalidGateway(String),

    /// VPN connection failed
    #[error("VPN connection failed: {0}")]
    VpnFailed(String),

    /// Bluetooth device not found
    #[error("Bluetooth device not found")]
    NoBluetoothDevice,

    /// A D-Bus operation failed with context about what was being attempted
    #[error("{context}: {source}")]
    DbusOperation {
        context: String,
        #[source]
        source: zbus::Error,
    },
}