product-os-proxy 0.0.19

Product OS : Proxy builds on the work of hudsucker, taking it to the next level with a man-in-the-middle proxy server that can tunnel traffic through a VPN utilising Product OS : VPN.
//! Proxy-specific error types for clearer handling and diagnostics.

use std::fmt;

/// Errors specific to the proxy lifecycle, build, and runtime.
///
/// Use this enum for pattern matching on proxy failures (e.g. cert load vs bind vs upstream).
#[derive(Debug)]
pub enum ProxyError {
    /// Certificate authority configuration or files are missing or invalid.
    CertLoadFailed(String),
    /// No certificate authority configuration was provided.
    NoCertificateAuthority,
    /// No certificate data was provided (e.g. empty cert list).
    NoCertsProvided,
    /// Proxy builder failed (missing address, client, or CA).
    BuildFailed(String),
    /// Tor client bootstrap or connection failed.
    TorBootstrapFailed(String),
    /// Tor tunnel requested but the `tor` feature is not enabled.
    TorFeatureDisabled,
    /// VPN tunnel requested but no VPN config was provided.
    VpnConfigMissing,
    /// VPN tunnel requested but the `vpn` feature is not enabled.
    VpnFeatureDisabled,
    /// Operation requires the proxy to be running (e.g. halt/rerun with no underlying proxy).
    NoUnderlyingProxy,
    /// Proxy task failed during startup or exited unexpectedly.
    StartupFailed(String),
    /// Generic proxy error with a message.
    Generic(String),
}

impl fmt::Display for ProxyError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::CertLoadFailed(msg) => write!(f, "certificate load failed: {msg}"),
            Self::NoCertificateAuthority => {
                f.write_str("no certificate authority configuration provided")
            }
            Self::NoCertsProvided => f.write_str("no certificate authority certs provided"),
            Self::BuildFailed(msg) => write!(f, "proxy build failed: {msg}"),
            Self::TorBootstrapFailed(msg) => write!(f, "Tor bootstrap failed: {msg}"),
            Self::TorFeatureDisabled => {
                f.write_str("Tor tunnel requested but 'tor' feature is not enabled")
            }
            Self::VpnConfigMissing => f.write_str("VPN tunnel enabled but no VPN config provided"),
            Self::VpnFeatureDisabled => {
                f.write_str("VPN tunnel requested but 'vpn' feature is not enabled")
            }
            Self::NoUnderlyingProxy => f.write_str("unable to locate underlying proxy"),
            Self::StartupFailed(msg) => write!(f, "proxy startup failed: {msg}"),
            Self::Generic(msg) => f.write_str(msg),
        }
    }
}

impl std::error::Error for ProxyError {}

impl From<ProxyError> for product_os_utilities::ProductOSError {
    fn from(e: ProxyError) -> Self {
        product_os_utilities::ProductOSError::GenericError(e.to_string())
    }
}