1use std::fmt;
2
3use crate::netstack::Error as NetstackError;
4
5#[derive(Debug, thiserror::Error, Clone, Copy, Eq, PartialEq)]
7pub enum Error {
8 #[error("operation timed-out")]
12 Timeout,
13
14 #[error("connection reset")]
18 ConnectionReset,
19
20 #[error("an error reading or parsing the key file")]
22 KeyFileRead,
23
24 #[error("an error writing out the key file")]
26 KeyFileWrite,
27
28 #[error("the environment variable `{}` was not set", crate::ENV_MAGIC_VAR)]
34 UnstableEnvVar,
35
36 #[error("no preferred DERP, try again later")]
43 NoPreferredDerp,
44
45 #[error("internal error ({0})")]
52 Internal(InternalErrorKind),
53}
54
55impl From<ts_runtime::SuggestExitNodeError> for Error {
56 fn from(value: ts_runtime::SuggestExitNodeError) -> Self {
57 match value {
58 ts_runtime::SuggestExitNodeError::NoPreferredDerp => Error::NoPreferredDerp,
59 }
60 }
61}
62
63#[non_exhaustive]
65#[derive(Debug, Clone, Copy, Eq, PartialEq)]
66pub enum InternalErrorKind {
67 InvalidSocketState,
69 InternalResponseMismatch,
71 InternalChannelClosed,
73 BadListenerHandle,
75 BadSocketHandle,
77 BadRequest,
79 BufferFull,
81 Actor,
83 UnsupportedInTunMode,
87 NetworkMonitorUnavailable,
92 NotFound,
94 AlreadyExists,
96 Io,
98}
99
100impl fmt::Display for InternalErrorKind {
101 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102 match self {
103 InternalErrorKind::InvalidSocketState => write!(f, "invalid socket state"),
104 InternalErrorKind::InternalResponseMismatch => {
105 write!(f, "response type mismatched to request type")
106 }
107 InternalErrorKind::InternalChannelClosed => write!(f, "channel closed"),
108 InternalErrorKind::BadListenerHandle => write!(f, "handle to invalid TCP listener"),
109 InternalErrorKind::BadSocketHandle => write!(f, "handle to invalid socket"),
110 InternalErrorKind::BadRequest => write!(f, "bad request"),
111 InternalErrorKind::BufferFull => write!(f, "buffer full"),
112 InternalErrorKind::Actor => write!(f, "actor missing or shutdown"),
113 InternalErrorKind::UnsupportedInTunMode => {
114 write!(f, "operation unsupported in TUN transport mode")
115 }
116 InternalErrorKind::NetworkMonitorUnavailable => {
117 write!(
118 f,
119 "network monitor requested but the `network-monitor` feature is disabled"
120 )
121 }
122 InternalErrorKind::NotFound => write!(f, "resource not found"),
123 InternalErrorKind::AlreadyExists => write!(f, "resource already exists"),
124 InternalErrorKind::Io => write!(f, "I/O error"),
125 }
126 }
127}
128
129impl From<crate::netstack::InternalErrorKind> for InternalErrorKind {
130 fn from(e: crate::netstack::InternalErrorKind) -> Self {
131 match e {
132 crate::netstack::InternalErrorKind::InvalidSocketState => {
133 InternalErrorKind::InvalidSocketState
134 }
135 crate::netstack::InternalErrorKind::InternalResponseMismatch => {
136 InternalErrorKind::InternalResponseMismatch
137 }
138 crate::netstack::InternalErrorKind::InternalChannelClosed => {
139 InternalErrorKind::InternalChannelClosed
140 }
141 crate::netstack::InternalErrorKind::BadListenerHandle => {
142 InternalErrorKind::BadListenerHandle
143 }
144 crate::netstack::InternalErrorKind::BadSocketHandle => {
145 InternalErrorKind::BadSocketHandle
146 }
147 crate::netstack::InternalErrorKind::BufferFull => InternalErrorKind::BufferFull,
148 _ => unreachable!(),
149 }
150 }
151}
152
153impl From<ts_runtime::Error> for Error {
154 fn from(value: ts_runtime::Error) -> Self {
155 match value.kind {
156 ts_runtime::ErrorKind::Timeout => Error::Timeout,
157 ts_runtime::ErrorKind::ActorGone
158 | ts_runtime::ErrorKind::MailboxFull
159 | ts_runtime::ErrorKind::ReplyErr => Error::Internal(InternalErrorKind::Actor),
160 ts_runtime::ErrorKind::UnsupportedInTunMode | ts_runtime::ErrorKind::TunUnavailable => {
163 Error::Internal(InternalErrorKind::UnsupportedInTunMode)
164 }
165 ts_runtime::ErrorKind::NetworkMonitorUnavailable => {
167 Error::Internal(InternalErrorKind::NetworkMonitorUnavailable)
168 }
169 }
170 }
171}
172
173impl From<NetstackError> for Error {
174 fn from(value: NetstackError) -> Self {
175 match value {
176 NetstackError::Internal(k) => Error::Internal(k.into()),
177 NetstackError::ConnectionReset => Error::ConnectionReset,
178 NetstackError::BadRequest(_) => Error::Internal(InternalErrorKind::BadRequest),
179 }
180 }
181}