summaryrefslogtreecommitdiffhomepage
path: root/mullvad-relay-selector/src/error.rs
blob: 0d5acf4ae8e5c4cf4b0f612196af41c557a53f64 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//! Definition of relay selector errors
#![allow(dead_code)]

use crate::{detailer, query::RelayQuery, relay_selector::relays::WireguardConfig};
use mullvad_types::{relay_constraints::MissingCustomBridgeSettings, relay_list::Relay};
use talpid_types::net::IpVersion;

#[derive(thiserror::Error, Debug)]
pub enum Error {
    #[error("Failed to open relay cache file")]
    OpenRelayCache(#[source] std::io::Error),

    #[error("Failed to write relay cache file to disk")]
    WriteRelayCache(#[source] std::io::Error),

    #[error("The combination of relay constraints is invalid")]
    InvalidConstraints,

    #[error("No relays matching current entry constraints: {0:?}")]
    NoRelayEntry(Box<RelayQuery>),

    #[error("No relays matching current exit constraints: {0:?}")]
    NoRelayExit(Box<RelayQuery>),

    #[error("No relays matching current constraints: {0:?}")]
    NoRelay(Box<RelayQuery>),

    #[error("No bridges matching current constraints")]
    NoBridge,

    #[error("No obfuscators matching current constraints")]
    NoObfuscator(#[source] Box<dyn std::error::Error + Send + Sync>),

    #[error("No endpoint could be constructed due to {} for relay {:?}", .internal, .relay)]
    NoEndpoint {
        internal: detailer::Error,
        relay: EndpointErrorDetails,
    },

    #[error("Failure in serialization of the relay list")]
    Serialize(#[from] serde_json::Error),

    #[error("Invalid bridge settings")]
    InvalidBridgeSettings(#[from] MissingCustomBridgeSettings),

    #[error("The requested IP version ({family}) does not match ip availability")]
    IpVersionUnavailable { family: IpVersion },
}

/// Special type which only shows up in [`Error`]. This error variant signals that no valid
/// endpoint could be constructed from the selected relay.
#[derive(Debug)]
pub enum EndpointErrorDetails {
    /// No valid Wireguard endpoint could be constructed from this [`WireguardConfig`].
    ///
    /// # Note
    /// The inner value is boxed to not bloat the size of [`Error`] due to the size of
    /// [`WireguardConfig`].
    Wireguard(Box<WireguardConfig>),
    /// No valid OpenVPN endpoint could be constructed from this [`Relay`]
    ///
    /// # Note
    /// The inner value is boxed to not bloat the size of [`Error`] due to the size of [`Relay`].
    OpenVpn(Box<Relay>),
}

impl EndpointErrorDetails {
    /// Helper function for constructing an [`Error::NoEndpoint`] from `relay`.
    /// Takes care of boxing the [`WireguardConfig`] for you!
    pub(crate) fn from_wireguard(relay: WireguardConfig) -> Self {
        EndpointErrorDetails::Wireguard(Box::new(relay))
    }

    /// Helper function for constructing an [`Error::NoEndpoint`] from `relay`.
    /// Takes care of boxing the [`Relay`] for you!
    pub(crate) fn from_openvpn(relay: Relay) -> Self {
        EndpointErrorDetails::OpenVpn(Box::new(relay))
    }
}