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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use futures::task::SpawnError;
use std::sync::Arc;
use std::time::Instant;
use tor_error::{Bug, ErrorKind, HasKind};
#[derive(Clone, Debug, thiserror::Error)]
#[non_exhaustive]
pub enum PickGuardError {
#[error("All guards are down")]
AllGuardsDown {
retry_at: Option<Instant>,
},
#[error("No running guards were usable for the selected purpose")]
NoGuardsUsable,
#[error("All fallback directories are down")]
AllFallbacksDown {
retry_at: Option<Instant>,
},
#[error("Tried to pick from an empty list")]
NoCandidatesAvailable,
#[error("Internal error")]
Internal(#[from] Bug),
}
impl tor_error::HasKind for PickGuardError {
fn kind(&self) -> tor_error::ErrorKind {
use tor_error::ErrorKind as EK;
use PickGuardError as E;
match self {
E::AllFallbacksDown { .. } | E::AllGuardsDown { .. } => EK::TorAccessFailed,
E::NoGuardsUsable | E::NoCandidatesAvailable => EK::NoPath,
E::Internal(_) => EK::Internal,
}
}
}
impl tor_error::HasRetryTime for PickGuardError {
fn retry_time(&self) -> tor_error::RetryTime {
use tor_error::RetryTime as RT;
use PickGuardError as E;
match self {
E::AllGuardsDown {
retry_at: Some(when),
} => RT::At(*when),
E::AllFallbacksDown {
retry_at: Some(when),
} => RT::At(*when),
E::AllGuardsDown { .. } | E::AllFallbacksDown { .. } => RT::AfterWaiting,
E::NoGuardsUsable | E::NoCandidatesAvailable => RT::Never,
E::Internal(_) => RT::Never,
}
}
}
#[derive(Clone, Debug, thiserror::Error)]
#[non_exhaustive]
pub enum GuardMgrError {
#[error("Problem accessing persistent state")]
State(#[from] tor_persist::Error),
#[error("Unable to spawn {spawning}")]
Spawn {
spawning: &'static str,
#[source]
cause: Arc<SpawnError>,
},
}
impl HasKind for GuardMgrError {
#[rustfmt::skip]
fn kind(&self) -> ErrorKind {
use GuardMgrError as G;
match self {
G::State(e) => e.kind(),
G::Spawn{ cause, .. } => cause.kind(),
}
}
}
impl GuardMgrError {
pub(crate) fn from_spawn(spawning: &'static str, err: SpawnError) -> GuardMgrError {
GuardMgrError::Spawn {
spawning,
cause: Arc::new(err),
}
}
}