1
//! Error types for the vanguards subsystem.
2

            
3
use std::sync::Arc;
4

            
5
use futures::task::SpawnError;
6
use tor_error::{ErrorKind, HasKind};
7

            
8
use crate::vanguards::{Layer, VanguardMode};
9

            
10
/// An error coming from the vanguards subsystem.
11
#[derive(Clone, Debug, thiserror::Error)]
12
#[non_exhaustive]
13
pub enum VanguardMgrError {
14
    /// Attempted to use an unbootstrapped `VanguardMgr` for something that
15
    /// requires bootstrapping to have completed.
16
    #[error("Cannot {action} with unbootstrapped vanguard manager")]
17
    BootstrapRequired {
18
        /// What we were trying to do that required bootstrapping.
19
        action: &'static str,
20
    },
21

            
22
    /// Attempted to select a vanguard layer that is not supported in the current [`VanguardMode`],
23
    #[error("{layer} vanguards are not supported in {mode} mode")]
24
    LayerNotSupported {
25
        /// The layer we tried to select a vanguard for.
26
        layer: Layer,
27
        /// The [`VanguardMode`] we are in.
28
        mode: VanguardMode,
29
    },
30

            
31
    /// Could not find a suitable relay to use for the specifier layer.
32
    #[error("No suitable relays")]
33
    NoSuitableRelay(Layer),
34

            
35
    /// Could not get timely network directory.
36
    #[error("Unable to get timely network directory")]
37
    NetDir(#[from] tor_netdir::Error),
38

            
39
    /// Failed to access persistent storage.
40
    #[error("Failed to access persistent vanguard state")]
41
    State(#[from] tor_persist::Error),
42

            
43
    /// Could not spawn a task.
44
    #[error("Unable to spawn a task")]
45
    Spawn(#[source] Arc<SpawnError>),
46

            
47
    /// An internal error occurred.
48
    #[error("Internal error")]
49
    Bug(#[from] tor_error::Bug),
50
}
51

            
52
impl HasKind for VanguardMgrError {
53
    fn kind(&self) -> ErrorKind {
54
        match self {
55
            VanguardMgrError::BootstrapRequired { .. } => ErrorKind::BootstrapRequired,
56
            VanguardMgrError::LayerNotSupported { .. } => ErrorKind::BadApiUsage,
57
            VanguardMgrError::NoSuitableRelay(_) => ErrorKind::NoPath,
58
            VanguardMgrError::NetDir(e) => e.kind(),
59
            VanguardMgrError::State(e) => e.kind(),
60
            VanguardMgrError::Spawn(e) => e.kind(),
61
            VanguardMgrError::Bug(e) => e.kind(),
62
        }
63
    }
64
}