/build/source/nativelink-error/src/lib.rs
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2024 The NativeLink Authors. All rights reserved. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | use std::convert::Into; |
16 | | |
17 | | use nativelink_metric::{ |
18 | | MetricFieldData, MetricKind, MetricPublishKnownKindData, MetricsComponent, |
19 | | }; |
20 | | use prost_types::TimestampError; |
21 | | use serde::{Deserialize, Serialize}; |
22 | | |
23 | | #[macro_export] |
24 | | macro_rules! make_err { |
25 | | ($code:expr, $($arg:tt)+) => {{ |
26 | | $crate::Error::new( |
27 | | $code, |
28 | | format!("{}", format_args!($($arg)+)), |
29 | | ) |
30 | | }}; |
31 | | } |
32 | | |
33 | | #[macro_export] |
34 | | macro_rules! make_input_err { |
35 | | ($($arg:tt)+) => {{ |
36 | | $crate::make_err!($crate::Code::InvalidArgument, $($arg)+) |
37 | | }}; |
38 | | } |
39 | | |
40 | | #[macro_export] |
41 | | macro_rules! error_if { |
42 | | ($cond:expr, $($arg:tt)+) => {{ |
43 | | if $cond { |
44 | | Err($crate::make_err!($crate::Code::InvalidArgument, $($arg)+))?; |
45 | | } |
46 | | }}; |
47 | | } |
48 | | |
49 | 0 | #[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)] |
50 | | pub struct Error { |
51 | | pub code: Code, |
52 | | pub messages: Vec<String>, |
53 | | } |
54 | | |
55 | | impl MetricsComponent for Error { |
56 | 0 | fn publish( |
57 | 0 | &self, |
58 | 0 | kind: MetricKind, |
59 | 0 | field_metadata: MetricFieldData, |
60 | 0 | ) -> Result<MetricPublishKnownKindData, nativelink_metric::Error> { |
61 | 0 | self.to_string().publish(kind, field_metadata) |
62 | 0 | } |
63 | | } |
64 | | |
65 | | impl Error { |
66 | 630 | pub fn new(code: Code, msg: String) -> Self { |
67 | 630 | let mut msgs = Vec::with_capacity(1); |
68 | 630 | if !msg.is_empty() { Branch (68:12): [True: 630, False: 0]
Branch (68:12): [Folded - Ignored]
|
69 | 630 | msgs.push(msg); |
70 | 630 | }0 |
71 | 630 | Self { |
72 | 630 | code, |
73 | 630 | messages: msgs, |
74 | 630 | } |
75 | 630 | } |
76 | | |
77 | | #[inline] |
78 | | #[must_use] |
79 | 18 | pub fn append<S: Into<String>>(mut self, msg: S) -> Self { |
80 | 18 | self.messages.push(msg.into()); |
81 | 18 | self |
82 | 18 | } |
83 | | |
84 | | #[must_use] |
85 | 2 | pub fn merge<E: Into<Self>>(mut self, other: E) -> Self { |
86 | 2 | let mut other: Self = other.into(); |
87 | 2 | // This will help with knowing which messages are tied to different errors. |
88 | 2 | self.messages.push("---".to_string()); |
89 | 2 | self.messages.append(&mut other.messages); |
90 | 2 | self |
91 | 2 | } |
92 | | |
93 | | #[must_use] |
94 | 6 | pub fn merge_option<T: Into<Self>, U: Into<Self>>( |
95 | 6 | this: Option<T>, |
96 | 6 | other: Option<U>, |
97 | 6 | ) -> Option<Self> { |
98 | 6 | if let Some(this1 ) = this { Branch (98:16): [Folded - Ignored]
Branch (98:16): [Folded - Ignored]
Branch (98:16): [True: 1, False: 5]
|
99 | 1 | if let Some(other0 ) = other { Branch (99:20): [Folded - Ignored]
Branch (99:20): [Folded - Ignored]
Branch (99:20): [True: 0, False: 1]
|
100 | 0 | return Some(this.into().merge(other)); |
101 | 1 | } |
102 | 1 | return Some(this.into()); |
103 | 5 | } |
104 | 5 | other.map(Into::into) |
105 | 6 | } |
106 | | |
107 | 1 | pub fn to_std_err(self) -> std::io::Error { |
108 | 1 | std::io::Error::new(self.code.into(), self.messages.join(" : ")) |
109 | 1 | } |
110 | | |
111 | 6 | pub fn message_string(&self) -> String { |
112 | 6 | self.messages.join(" : ") |
113 | 6 | } |
114 | | } |
115 | | |
116 | | impl std::error::Error for Error {} |
117 | | |
118 | | impl From<Error> for nativelink_proto::google::rpc::Status { |
119 | 6 | fn from(val: Error) -> Self { |
120 | 6 | Self { |
121 | 6 | code: val.code as i32, |
122 | 6 | message: val.message_string(), |
123 | 6 | details: vec![], |
124 | 6 | } |
125 | 6 | } |
126 | | } |
127 | | |
128 | | impl From<nativelink_proto::google::rpc::Status> for Error { |
129 | 2 | fn from(val: nativelink_proto::google::rpc::Status) -> Self { |
130 | 2 | Self { |
131 | 2 | code: val.code.into(), |
132 | 2 | messages: vec![val.message], |
133 | 2 | } |
134 | 2 | } |
135 | | } |
136 | | |
137 | | impl std::fmt::Display for Error { |
138 | 8 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
139 | 8 | // A manual impl to reduce the noise of frequently empty fields. |
140 | 8 | let mut builder = f.debug_struct("Error"); |
141 | 8 | |
142 | 8 | builder.field("code", &self.code); |
143 | 8 | |
144 | 8 | if !self.messages.is_empty() { Branch (144:12): [True: 8, False: 0]
Branch (144:12): [Folded - Ignored]
|
145 | 8 | builder.field("messages", &self.messages); |
146 | 8 | }0 |
147 | | |
148 | 8 | builder.finish() |
149 | 8 | } |
150 | | } |
151 | | |
152 | | impl From<prost::DecodeError> for Error { |
153 | 0 | fn from(err: prost::DecodeError) -> Self { |
154 | 0 | make_err!(Code::Internal, "{}", err.to_string()) |
155 | 0 | } |
156 | | } |
157 | | |
158 | | impl From<prost::EncodeError> for Error { |
159 | 0 | fn from(err: prost::EncodeError) -> Self { |
160 | 0 | make_err!(Code::Internal, "{}", err.to_string()) |
161 | 0 | } |
162 | | } |
163 | | |
164 | | impl From<prost::UnknownEnumValue> for Error { |
165 | 0 | fn from(err: prost::UnknownEnumValue) -> Self { |
166 | 0 | make_err!(Code::Internal, "{}", err.to_string()) |
167 | 0 | } |
168 | | } |
169 | | |
170 | | impl From<std::num::TryFromIntError> for Error { |
171 | 0 | fn from(err: std::num::TryFromIntError) -> Self { |
172 | 0 | make_err!(Code::InvalidArgument, "{}", err.to_string()) |
173 | 0 | } |
174 | | } |
175 | | |
176 | | impl From<tokio::task::JoinError> for Error { |
177 | 0 | fn from(err: tokio::task::JoinError) -> Self { |
178 | 0 | make_err!(Code::Internal, "{}", err.to_string()) |
179 | 0 | } |
180 | | } |
181 | | |
182 | | impl From<std::num::ParseIntError> for Error { |
183 | 0 | fn from(err: std::num::ParseIntError) -> Self { |
184 | 0 | make_err!(Code::InvalidArgument, "{}", err.to_string()) |
185 | 0 | } |
186 | | } |
187 | | |
188 | | impl From<hex::FromHexError> for Error { |
189 | 0 | fn from(err: hex::FromHexError) -> Self { |
190 | 0 | make_err!(Code::InvalidArgument, "{}", err.to_string()) |
191 | 0 | } |
192 | | } |
193 | | |
194 | | impl From<std::convert::Infallible> for Error { |
195 | 0 | fn from(_err: std::convert::Infallible) -> Self { |
196 | 0 | // Infallible is an error type that can never happen. |
197 | 0 | unreachable!(); |
198 | | } |
199 | | } |
200 | | |
201 | | impl From<TimestampError> for Error { |
202 | 0 | fn from(err: TimestampError) -> Self { |
203 | 0 | make_err!(Code::InvalidArgument, "{}", err) |
204 | 0 | } |
205 | | } |
206 | | |
207 | | impl From<std::io::Error> for Error { |
208 | 5 | fn from(err: std::io::Error) -> Self { |
209 | 5 | Self { |
210 | 5 | code: err.kind().into(), |
211 | 5 | messages: vec![err.to_string()], |
212 | 5 | } |
213 | 5 | } |
214 | | } |
215 | | |
216 | | impl From<Code> for Error { |
217 | 0 | fn from(code: Code) -> Self { |
218 | 0 | make_err!(code, "") |
219 | 0 | } |
220 | | } |
221 | | |
222 | | impl From<fred::error::RedisError> for Error { |
223 | 0 | fn from(error: fred::error::RedisError) -> Self { |
224 | | use fred::error::RedisErrorKind::{ |
225 | | Auth, Backpressure, Canceled, Cluster, Config, InvalidArgument, InvalidCommand, |
226 | | NotFound, Parse, Protocol, Sentinel, Timeout, Tls, Unknown, Url, IO, |
227 | | }; |
228 | | |
229 | | // Conversions here are based on https://grpc.github.io/grpc/core/md_doc_statuscodes.html. |
230 | 0 | let code = match error.kind() { |
231 | 0 | Config | InvalidCommand | InvalidArgument | Url => Code::InvalidArgument, |
232 | 0 | IO | Protocol | Tls | Cluster | Parse | Sentinel => Code::Internal, |
233 | 0 | Auth => Code::PermissionDenied, |
234 | 0 | Canceled => Code::Aborted, |
235 | 0 | Unknown => Code::Unknown, |
236 | 0 | Timeout => Code::DeadlineExceeded, |
237 | 0 | NotFound => Code::NotFound, |
238 | 0 | Backpressure => Code::Unavailable, |
239 | | }; |
240 | | |
241 | 0 | make_err!(code, "{error}") |
242 | 0 | } |
243 | | } |
244 | | |
245 | | impl From<tonic::transport::Error> for Error { |
246 | 0 | fn from(error: tonic::transport::Error) -> Self { |
247 | 0 | make_err!(Code::Internal, "{}", error.to_string()) |
248 | 0 | } |
249 | | } |
250 | | |
251 | | impl From<tonic::Status> for Error { |
252 | 2 | fn from(status: tonic::Status) -> Self { |
253 | 2 | make_err!(status.code().into(), "{}", status.to_string()) |
254 | 2 | } |
255 | | } |
256 | | |
257 | | impl From<Error> for tonic::Status { |
258 | 11 | fn from(val: Error) -> Self { |
259 | 11 | Self::new(val.code.into(), val.messages.join(" : ")) |
260 | 11 | } |
261 | | } |
262 | | |
263 | | pub trait ResultExt<T> { |
264 | | fn err_tip_with_code<F, S>(self, tip_fn: F) -> Result<T, Error> |
265 | | where |
266 | | Self: Sized, |
267 | | S: std::string::ToString, |
268 | | F: (std::ops::FnOnce(&Error) -> (Code, S)) + Sized; |
269 | | |
270 | | #[inline] |
271 | 159k | fn err_tip<F, S>(self, tip_fn: F) -> Result<T, Error> |
272 | 159k | where |
273 | 159k | Self: Sized, |
274 | 159k | S: std::string::ToString, |
275 | 159k | F: (std::ops::FnOnce() -> S) + Sized, |
276 | 159k | { |
277 | 159k | self.err_tip_with_code(|e| (e.code, tip_fn())97 ) |
278 | 159k | } |
279 | | |
280 | 0 | fn merge<U>(self, _other: Result<U, Error>) -> Result<U, Error> |
281 | 0 | where |
282 | 0 | Self: Sized, |
283 | 0 | { |
284 | 0 | unreachable!(); |
285 | | } |
286 | | } |
287 | | |
288 | | impl<T, E: Into<Error>> ResultExt<T> for Result<T, E> { |
289 | | #[inline] |
290 | 158k | fn err_tip_with_code<F, S>(self, tip_fn: F) -> Result<T, Error> |
291 | 158k | where |
292 | 158k | Self: Sized, |
293 | 158k | S: std::string::ToString, |
294 | 158k | F: (std::ops::FnOnce(&Error) -> (Code, S)) + Sized, |
295 | 158k | { |
296 | 158k | self.map_err(|e| { |
297 | 87 | let mut error: Error = e.into(); |
298 | 87 | let (code, message) = tip_fn(&error); |
299 | 87 | error.code = code; |
300 | 87 | error.messages.push(message.to_string()); |
301 | 87 | error |
302 | 158k | }) |
303 | 158k | } |
304 | | |
305 | 5.64k | fn merge<U>(self, other: Result<U, Error>) -> Result<U, Error> |
306 | 5.64k | where |
307 | 5.64k | Self: Sized, |
308 | 5.64k | { |
309 | 5.64k | if let Err(e15 ) = self { Branch (309:16): [Folded - Ignored]
Branch (309:16): [True: 0, False: 0]
Branch (309:16): [True: 1, False: 5]
Branch (309:16): [True: 3, False: 37]
Branch (309:16): [True: 4, False: 158]
Branch (309:16): [True: 0, False: 1]
Branch (309:16): [True: 0, False: 1]
Branch (309:16): [True: 0, False: 0]
Branch (309:16): [True: 0, False: 0]
Branch (309:16): [True: 1, False: 17]
Branch (309:16): [True: 0, False: 0]
Branch (309:16): [True: 0, False: 1.23k]
Branch (309:16): [True: 0, False: 1]
Branch (309:16): [True: 3, False: 4.04k]
Branch (309:16): [True: 0, False: 0]
Branch (309:16): [True: 0, False: 1]
Branch (309:16): [True: 0, False: 0]
Branch (309:16): [True: 0, False: 10]
Branch (309:16): [True: 0, False: 1]
Branch (309:16): [True: 0, False: 3]
Branch (309:16): [True: 0, False: 2]
Branch (309:16): [True: 0, False: 0]
Branch (309:16): [True: 0, False: 0]
Branch (309:16): [True: 0, False: 0]
Branch (309:16): [True: 0, False: 16]
Branch (309:16): [True: 0, False: 4]
Branch (309:16): [True: 1, False: 3]
Branch (309:16): [True: 0, False: 0]
Branch (309:16): [Folded - Ignored]
Branch (309:16): [True: 0, False: 0]
Branch (309:16): [True: 1, False: 4]
Branch (309:16): [True: 0, False: 0]
Branch (309:16): [True: 0, False: 2]
Branch (309:16): [True: 0, False: 0]
Branch (309:16): [True: 0, False: 0]
Branch (309:16): [True: 0, False: 0]
Branch (309:16): [True: 0, False: 25]
Branch (309:16): [True: 0, False: 5]
Branch (309:16): [True: 0, False: 4]
Branch (309:16): [True: 0, False: 1]
Branch (309:16): [True: 0, False: 5]
Branch (309:16): [True: 0, False: 0]
Branch (309:16): [True: 1, False: 43]
Branch (309:16): [True: 0, False: 4]
Branch (309:16): [True: 0, False: 0]
Branch (309:16): [True: 0, False: 0]
Branch (309:16): [True: 0, False: 0]
Branch (309:16): [True: 0, False: 0]
|
310 | 15 | let mut e: Error = e.into(); |
311 | 15 | if let Err(other_err13 ) = other { Branch (311:20): [Folded - Ignored]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 1]
Branch (311:20): [True: 3, False: 0]
Branch (311:20): [True: 4, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 1, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 3, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 1, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [Folded - Ignored]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 1, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 1]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
Branch (311:20): [True: 0, False: 0]
|
312 | 13 | let mut other_err: Error = other_err; |
313 | 13 | // This will help with knowing which messages are tied to different errors. |
314 | 13 | e.messages.push("---".to_string()); |
315 | 13 | e.messages.append(&mut other_err.messages); |
316 | 13 | }2 |
317 | 15 | return Err(e); |
318 | 5.63k | } |
319 | 5.63k | other |
320 | 5.64k | } |
321 | | } |
322 | | |
323 | | impl<T> ResultExt<T> for Option<T> { |
324 | | #[inline] |
325 | 5.44k | fn err_tip_with_code<F, S>(self, tip_fn: F) -> Result<T, Error> |
326 | 5.44k | where |
327 | 5.44k | Self: Sized, |
328 | 5.44k | S: std::string::ToString, |
329 | 5.44k | F: (std::ops::FnOnce(&Error) -> (Code, S)) + Sized, |
330 | 5.44k | { |
331 | 5.44k | self.ok_or_else(|| { |
332 | 17 | let mut error = Error { |
333 | 17 | code: Code::Internal, |
334 | 17 | messages: vec![], |
335 | 17 | }; |
336 | 17 | let (code, message) = tip_fn(&error); |
337 | 17 | error.code = code; |
338 | 17 | error.messages.push(message.to_string()); |
339 | 17 | error |
340 | 5.44k | }) |
341 | 5.44k | } |
342 | | } |
343 | | |
344 | 0 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] |
345 | | #[non_exhaustive] // New Codes may be added in the future, so never exhaustively match! |
346 | | pub enum Code { |
347 | | Ok = 0, |
348 | | Cancelled = 1, |
349 | | Unknown = 2, |
350 | | InvalidArgument = 3, |
351 | | DeadlineExceeded = 4, |
352 | | NotFound = 5, |
353 | | AlreadyExists = 6, |
354 | | PermissionDenied = 7, |
355 | | ResourceExhausted = 8, |
356 | | FailedPrecondition = 9, |
357 | | Aborted = 10, |
358 | | OutOfRange = 11, |
359 | | Unimplemented = 12, |
360 | | Internal = 13, |
361 | | Unavailable = 14, |
362 | | DataLoss = 15, |
363 | | Unauthenticated = 16, |
364 | | // NOTE: Additional codes must be added to stores.rs in ErrorCodes and also |
365 | | // in both match statements in retry.rs. |
366 | | } |
367 | | |
368 | | impl From<i32> for Code { |
369 | 2 | fn from(code: i32) -> Self { |
370 | 2 | match code { |
371 | 2 | x0 if x == Self::Ok as i32 => Self::Ok0 , Branch (371:18): [True: 0, False: 2]
Branch (371:18): [Folded - Ignored]
|
372 | 2 | x0 if x == Self::Cancelled as i32 => Self::Cancelled0 , Branch (372:18): [True: 0, False: 2]
Branch (372:18): [Folded - Ignored]
|
373 | 2 | x0 if x == Self::Unknown as i32 => Self::Unknown0 , Branch (373:18): [True: 0, False: 2]
Branch (373:18): [Folded - Ignored]
|
374 | 2 | x0 if x == Self::InvalidArgument as i32 => Self::InvalidArgument0 , Branch (374:18): [True: 0, False: 2]
Branch (374:18): [Folded - Ignored]
|
375 | 2 | x0 if x == Self::DeadlineExceeded as i32 => Self::DeadlineExceeded0 , Branch (375:18): [True: 0, False: 2]
Branch (375:18): [Folded - Ignored]
|
376 | 2 | x0 if x == Self::NotFound as i32 => Self::NotFound0 , Branch (376:18): [True: 0, False: 2]
Branch (376:18): [Folded - Ignored]
|
377 | 2 | x0 if x == Self::AlreadyExists as i32 => Self::AlreadyExists0 , Branch (377:18): [True: 0, False: 2]
Branch (377:18): [Folded - Ignored]
|
378 | 2 | x0 if x == Self::PermissionDenied as i32 => Self::PermissionDenied0 , Branch (378:18): [True: 0, False: 2]
Branch (378:18): [Folded - Ignored]
|
379 | 2 | x0 if x == Self::ResourceExhausted as i32 => Self::ResourceExhausted0 , Branch (379:18): [True: 0, False: 2]
Branch (379:18): [Folded - Ignored]
|
380 | 2 | x if x == Self::FailedPrecondition as i32 => Self::FailedPrecondition, Branch (380:18): [True: 2, False: 0]
Branch (380:18): [Folded - Ignored]
|
381 | 0 | x if x == Self::Aborted as i32 => Self::Aborted, Branch (381:18): [True: 0, False: 0]
Branch (381:18): [Folded - Ignored]
|
382 | 0 | x if x == Self::OutOfRange as i32 => Self::OutOfRange, Branch (382:18): [True: 0, False: 0]
Branch (382:18): [Folded - Ignored]
|
383 | 0 | x if x == Self::Unimplemented as i32 => Self::Unimplemented, Branch (383:18): [True: 0, False: 0]
Branch (383:18): [Folded - Ignored]
|
384 | 0 | x if x == Self::Internal as i32 => Self::Internal, Branch (384:18): [True: 0, False: 0]
Branch (384:18): [Folded - Ignored]
|
385 | 0 | x if x == Self::Unavailable as i32 => Self::Unavailable, Branch (385:18): [True: 0, False: 0]
Branch (385:18): [Folded - Ignored]
|
386 | 0 | x if x == Self::DataLoss as i32 => Self::DataLoss, Branch (386:18): [True: 0, False: 0]
Branch (386:18): [Folded - Ignored]
|
387 | 0 | x if x == Self::Unauthenticated as i32 => Self::Unauthenticated, Branch (387:18): [True: 0, False: 0]
Branch (387:18): [Folded - Ignored]
|
388 | 0 | _ => Self::Unknown, |
389 | | } |
390 | 2 | } |
391 | | } |
392 | | |
393 | | impl From<tonic::Code> for Code { |
394 | 2 | fn from(code: tonic::Code) -> Self { |
395 | 2 | match code { |
396 | 0 | tonic::Code::Ok => Self::Ok, |
397 | 0 | tonic::Code::Cancelled => Self::Cancelled, |
398 | 0 | tonic::Code::Unknown => Self::Unknown, |
399 | 0 | tonic::Code::InvalidArgument => Self::InvalidArgument, |
400 | 0 | tonic::Code::DeadlineExceeded => Self::DeadlineExceeded, |
401 | 1 | tonic::Code::NotFound => Self::NotFound, |
402 | 0 | tonic::Code::AlreadyExists => Self::AlreadyExists, |
403 | 0 | tonic::Code::PermissionDenied => Self::PermissionDenied, |
404 | 0 | tonic::Code::ResourceExhausted => Self::ResourceExhausted, |
405 | 0 | tonic::Code::FailedPrecondition => Self::FailedPrecondition, |
406 | 0 | tonic::Code::Aborted => Self::Aborted, |
407 | 1 | tonic::Code::OutOfRange => Self::OutOfRange, |
408 | 0 | tonic::Code::Unimplemented => Self::Unimplemented, |
409 | 0 | tonic::Code::Internal => Self::Internal, |
410 | 0 | tonic::Code::Unavailable => Self::Unavailable, |
411 | 0 | tonic::Code::DataLoss => Self::DataLoss, |
412 | 0 | tonic::Code::Unauthenticated => Self::Unauthenticated, |
413 | | } |
414 | 2 | } |
415 | | } |
416 | | |
417 | | impl From<Code> for tonic::Code { |
418 | 11 | fn from(val: Code) -> Self { |
419 | 11 | match val { |
420 | 0 | Code::Ok => Self::Ok, |
421 | 0 | Code::Cancelled => Self::Cancelled, |
422 | 0 | Code::Unknown => Self::Unknown, |
423 | 7 | Code::InvalidArgument => Self::InvalidArgument, |
424 | 0 | Code::DeadlineExceeded => Self::DeadlineExceeded, |
425 | 3 | Code::NotFound => Self::NotFound, |
426 | 0 | Code::AlreadyExists => Self::AlreadyExists, |
427 | 0 | Code::PermissionDenied => Self::PermissionDenied, |
428 | 0 | Code::ResourceExhausted => Self::ResourceExhausted, |
429 | 0 | Code::FailedPrecondition => Self::FailedPrecondition, |
430 | 0 | Code::Aborted => Self::Aborted, |
431 | 1 | Code::OutOfRange => Self::OutOfRange, |
432 | 0 | Code::Unimplemented => Self::Unimplemented, |
433 | 0 | Code::Internal => Self::Internal, |
434 | 0 | Code::Unavailable => Self::Unavailable, |
435 | 0 | Code::DataLoss => Self::DataLoss, |
436 | 0 | Code::Unauthenticated => Self::Unauthenticated, |
437 | | } |
438 | 11 | } |
439 | | } |
440 | | |
441 | | impl From<std::io::ErrorKind> for Code { |
442 | 5 | fn from(kind: std::io::ErrorKind) -> Self { |
443 | 5 | match kind { |
444 | 4 | std::io::ErrorKind::NotFound => Self::NotFound, |
445 | 0 | std::io::ErrorKind::PermissionDenied => Self::PermissionDenied, |
446 | | std::io::ErrorKind::ConnectionRefused |
447 | | | std::io::ErrorKind::ConnectionReset |
448 | 0 | | std::io::ErrorKind::ConnectionAborted => Self::Unavailable, |
449 | 0 | std::io::ErrorKind::AlreadyExists => Self::AlreadyExists, |
450 | | std::io::ErrorKind::InvalidInput | std::io::ErrorKind::InvalidData => { |
451 | 0 | Self::InvalidArgument |
452 | | } |
453 | 0 | std::io::ErrorKind::TimedOut => Self::DeadlineExceeded, |
454 | 0 | std::io::ErrorKind::Interrupted => Self::Aborted, |
455 | | std::io::ErrorKind::NotConnected |
456 | | | std::io::ErrorKind::AddrInUse |
457 | | | std::io::ErrorKind::AddrNotAvailable |
458 | | | std::io::ErrorKind::BrokenPipe |
459 | | | std::io::ErrorKind::WouldBlock |
460 | | | std::io::ErrorKind::WriteZero |
461 | | | std::io::ErrorKind::Other |
462 | 1 | | std::io::ErrorKind::UnexpectedEof => Self::Internal, |
463 | 0 | _ => Self::Unknown, |
464 | | } |
465 | 5 | } |
466 | | } |
467 | | |
468 | | impl From<Code> for std::io::ErrorKind { |
469 | 1 | fn from(kind: Code) -> Self { |
470 | 1 | match kind { |
471 | 0 | Code::Aborted => Self::Interrupted, |
472 | 0 | Code::AlreadyExists => Self::AlreadyExists, |
473 | 0 | Code::DeadlineExceeded => Self::TimedOut, |
474 | 0 | Code::InvalidArgument => Self::InvalidInput, |
475 | 0 | Code::NotFound => Self::NotFound, |
476 | 0 | Code::PermissionDenied => Self::PermissionDenied, |
477 | 0 | Code::Unavailable => Self::ConnectionRefused, |
478 | 1 | _ => Self::Other, |
479 | | } |
480 | 1 | } |
481 | | } |
482 | | |
483 | | // Allows for mapping this type into a generic serialization error. |
484 | | impl serde::ser::Error for Error { |
485 | 0 | fn custom<T: std::fmt::Display>(msg: T) -> Self { |
486 | 0 | Self::new(Code::InvalidArgument, msg.to_string()) |
487 | 0 | } |
488 | | } |
489 | | |
490 | | // Allows for mapping this type into a generic deserialization error. |
491 | | impl serde::de::Error for Error { |
492 | 0 | fn custom<T: std::fmt::Display>(msg: T) -> Self { |
493 | 0 | Self::new(Code::InvalidArgument, msg.to_string()) |
494 | 0 | } |
495 | | } |