Skip to content

Commit a204116

Browse files
authored
Remove indirection for wrapping tonic error codes (#1656)
There is no need to use a custom type here. Also removes some unused existing trait implementations.
1 parent 1982938 commit a204116

File tree

1 file changed

+59
-154
lines changed

1 file changed

+59
-154
lines changed

nativelink-error/src/lib.rs

Lines changed: 59 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ use nativelink_metric::{
1919
};
2020
use prost_types::TimestampError;
2121
use serde::{Deserialize, Serialize};
22+
// Reexport of tonic's error codes which we use as "nativelink_error::Code".
23+
pub use tonic::Code;
2224

2325
#[macro_export]
2426
macro_rules! make_err {
@@ -48,6 +50,7 @@ macro_rules! error_if {
4850

4951
#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)]
5052
pub struct Error {
53+
#[serde(with = "CodeDef")]
5154
pub code: Code,
5255
pub messages: Vec<String>,
5356
}
@@ -105,7 +108,7 @@ impl Error {
105108
}
106109

107110
pub fn to_std_err(self) -> std::io::Error {
108-
std::io::Error::new(self.code.into(), self.messages.join(" : "))
111+
std::io::Error::new(self.code.into_error_kind(), self.messages.join(" : "))
109112
}
110113

111114
pub fn message_string(&self) -> String {
@@ -185,12 +188,6 @@ impl From<std::num::ParseIntError> for Error {
185188
}
186189
}
187190

188-
impl From<hex::FromHexError> for Error {
189-
fn from(err: hex::FromHexError) -> Self {
190-
make_err!(Code::InvalidArgument, "{}", err.to_string())
191-
}
192-
}
193-
194191
impl From<std::convert::Infallible> for Error {
195192
fn from(_err: std::convert::Infallible) -> Self {
196193
// Infallible is an error type that can never happen.
@@ -207,18 +204,12 @@ impl From<TimestampError> for Error {
207204
impl From<std::io::Error> for Error {
208205
fn from(err: std::io::Error) -> Self {
209206
Self {
210-
code: err.kind().into(),
207+
code: err.kind().into_code(),
211208
messages: vec![err.to_string()],
212209
}
213210
}
214211
}
215212

216-
impl From<Code> for Error {
217-
fn from(code: Code) -> Self {
218-
make_err!(code, "")
219-
}
220-
}
221-
222213
impl From<fred::error::Error> for Error {
223214
fn from(error: fred::error::Error) -> Self {
224215
use fred::error::ErrorKind::{
@@ -242,21 +233,15 @@ impl From<fred::error::Error> for Error {
242233
}
243234
}
244235

245-
impl From<tonic::transport::Error> for Error {
246-
fn from(error: tonic::transport::Error) -> Self {
247-
make_err!(Code::Internal, "{}", error.to_string())
248-
}
249-
}
250-
251236
impl From<tonic::Status> for Error {
252237
fn from(status: tonic::Status) -> Self {
253-
make_err!(status.code().into(), "{}", status.to_string())
238+
make_err!(status.code(), "{}", status.to_string())
254239
}
255240
}
256241

257242
impl From<Error> for tonic::Status {
258243
fn from(val: Error) -> Self {
259-
Self::new(val.code.into(), val.messages.join(" : "))
244+
Self::new(val.code, val.messages.join(" : "))
260245
}
261246
}
262247

@@ -341,9 +326,58 @@ impl<T> ResultExt<T> for Option<T> {
341326
}
342327
}
343328

344-
#[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 {
329+
trait CodeExt {
330+
fn into_error_kind(self) -> std::io::ErrorKind;
331+
}
332+
333+
impl CodeExt for Code {
334+
fn into_error_kind(self) -> std::io::ErrorKind {
335+
match self {
336+
Code::Aborted => std::io::ErrorKind::Interrupted,
337+
Code::AlreadyExists => std::io::ErrorKind::AlreadyExists,
338+
Code::DeadlineExceeded => std::io::ErrorKind::TimedOut,
339+
Code::InvalidArgument => std::io::ErrorKind::InvalidInput,
340+
Code::NotFound => std::io::ErrorKind::NotFound,
341+
Code::PermissionDenied => std::io::ErrorKind::PermissionDenied,
342+
Code::Unavailable => std::io::ErrorKind::ConnectionRefused,
343+
_ => std::io::ErrorKind::Other,
344+
}
345+
}
346+
}
347+
348+
trait ErrorKindExt {
349+
fn into_code(self) -> Code;
350+
}
351+
352+
impl ErrorKindExt for std::io::ErrorKind {
353+
fn into_code(self) -> Code {
354+
match self {
355+
Self::NotFound => Code::NotFound,
356+
Self::PermissionDenied => Code::PermissionDenied,
357+
Self::ConnectionRefused | Self::ConnectionReset | Self::ConnectionAborted => {
358+
Code::Unavailable
359+
}
360+
Self::AlreadyExists => Code::AlreadyExists,
361+
Self::InvalidInput | Self::InvalidData => Code::InvalidArgument,
362+
Self::TimedOut => Code::DeadlineExceeded,
363+
Self::Interrupted => Code::Aborted,
364+
Self::NotConnected
365+
| Self::AddrInUse
366+
| Self::AddrNotAvailable
367+
| Self::BrokenPipe
368+
| Self::WouldBlock
369+
| Self::WriteZero
370+
| Self::Other
371+
| Self::UnexpectedEof => Code::Internal,
372+
_ => Code::Unknown,
373+
}
374+
}
375+
}
376+
377+
// Serde definition for tonic::Code. See: https://serde.rs/remote-derive.html
378+
#[derive(Serialize, Deserialize)]
379+
#[serde(remote = "Code")]
380+
pub enum CodeDef {
347381
Ok = 0,
348382
Cancelled = 1,
349383
Unknown = 2,
@@ -364,132 +398,3 @@ pub enum Code {
364398
// NOTE: Additional codes must be added to stores.rs in ErrorCodes and also
365399
// in both match statements in retry.rs.
366400
}
367-
368-
impl From<i32> for Code {
369-
fn from(code: i32) -> Self {
370-
match code {
371-
x if x == Self::Ok as i32 => Self::Ok,
372-
x if x == Self::Cancelled as i32 => Self::Cancelled,
373-
x if x == Self::Unknown as i32 => Self::Unknown,
374-
x if x == Self::InvalidArgument as i32 => Self::InvalidArgument,
375-
x if x == Self::DeadlineExceeded as i32 => Self::DeadlineExceeded,
376-
x if x == Self::NotFound as i32 => Self::NotFound,
377-
x if x == Self::AlreadyExists as i32 => Self::AlreadyExists,
378-
x if x == Self::PermissionDenied as i32 => Self::PermissionDenied,
379-
x if x == Self::ResourceExhausted as i32 => Self::ResourceExhausted,
380-
x if x == Self::FailedPrecondition as i32 => Self::FailedPrecondition,
381-
x if x == Self::Aborted as i32 => Self::Aborted,
382-
x if x == Self::OutOfRange as i32 => Self::OutOfRange,
383-
x if x == Self::Unimplemented as i32 => Self::Unimplemented,
384-
x if x == Self::Internal as i32 => Self::Internal,
385-
x if x == Self::Unavailable as i32 => Self::Unavailable,
386-
x if x == Self::DataLoss as i32 => Self::DataLoss,
387-
x if x == Self::Unauthenticated as i32 => Self::Unauthenticated,
388-
_ => Self::Unknown,
389-
}
390-
}
391-
}
392-
393-
impl From<tonic::Code> for Code {
394-
fn from(code: tonic::Code) -> Self {
395-
match code {
396-
tonic::Code::Ok => Self::Ok,
397-
tonic::Code::Cancelled => Self::Cancelled,
398-
tonic::Code::Unknown => Self::Unknown,
399-
tonic::Code::InvalidArgument => Self::InvalidArgument,
400-
tonic::Code::DeadlineExceeded => Self::DeadlineExceeded,
401-
tonic::Code::NotFound => Self::NotFound,
402-
tonic::Code::AlreadyExists => Self::AlreadyExists,
403-
tonic::Code::PermissionDenied => Self::PermissionDenied,
404-
tonic::Code::ResourceExhausted => Self::ResourceExhausted,
405-
tonic::Code::FailedPrecondition => Self::FailedPrecondition,
406-
tonic::Code::Aborted => Self::Aborted,
407-
tonic::Code::OutOfRange => Self::OutOfRange,
408-
tonic::Code::Unimplemented => Self::Unimplemented,
409-
tonic::Code::Internal => Self::Internal,
410-
tonic::Code::Unavailable => Self::Unavailable,
411-
tonic::Code::DataLoss => Self::DataLoss,
412-
tonic::Code::Unauthenticated => Self::Unauthenticated,
413-
}
414-
}
415-
}
416-
417-
impl From<Code> for tonic::Code {
418-
fn from(val: Code) -> Self {
419-
match val {
420-
Code::Ok => Self::Ok,
421-
Code::Cancelled => Self::Cancelled,
422-
Code::Unknown => Self::Unknown,
423-
Code::InvalidArgument => Self::InvalidArgument,
424-
Code::DeadlineExceeded => Self::DeadlineExceeded,
425-
Code::NotFound => Self::NotFound,
426-
Code::AlreadyExists => Self::AlreadyExists,
427-
Code::PermissionDenied => Self::PermissionDenied,
428-
Code::ResourceExhausted => Self::ResourceExhausted,
429-
Code::FailedPrecondition => Self::FailedPrecondition,
430-
Code::Aborted => Self::Aborted,
431-
Code::OutOfRange => Self::OutOfRange,
432-
Code::Unimplemented => Self::Unimplemented,
433-
Code::Internal => Self::Internal,
434-
Code::Unavailable => Self::Unavailable,
435-
Code::DataLoss => Self::DataLoss,
436-
Code::Unauthenticated => Self::Unauthenticated,
437-
}
438-
}
439-
}
440-
441-
impl From<std::io::ErrorKind> for Code {
442-
fn from(kind: std::io::ErrorKind) -> Self {
443-
match kind {
444-
std::io::ErrorKind::NotFound => Self::NotFound,
445-
std::io::ErrorKind::PermissionDenied => Self::PermissionDenied,
446-
std::io::ErrorKind::ConnectionRefused
447-
| std::io::ErrorKind::ConnectionReset
448-
| std::io::ErrorKind::ConnectionAborted => Self::Unavailable,
449-
std::io::ErrorKind::AlreadyExists => Self::AlreadyExists,
450-
std::io::ErrorKind::InvalidInput | std::io::ErrorKind::InvalidData => {
451-
Self::InvalidArgument
452-
}
453-
std::io::ErrorKind::TimedOut => Self::DeadlineExceeded,
454-
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-
| std::io::ErrorKind::UnexpectedEof => Self::Internal,
463-
_ => Self::Unknown,
464-
}
465-
}
466-
}
467-
468-
impl From<Code> for std::io::ErrorKind {
469-
fn from(kind: Code) -> Self {
470-
match kind {
471-
Code::Aborted => Self::Interrupted,
472-
Code::AlreadyExists => Self::AlreadyExists,
473-
Code::DeadlineExceeded => Self::TimedOut,
474-
Code::InvalidArgument => Self::InvalidInput,
475-
Code::NotFound => Self::NotFound,
476-
Code::PermissionDenied => Self::PermissionDenied,
477-
Code::Unavailable => Self::ConnectionRefused,
478-
_ => Self::Other,
479-
}
480-
}
481-
}
482-
483-
// Allows for mapping this type into a generic serialization error.
484-
impl serde::ser::Error for Error {
485-
fn custom<T: std::fmt::Display>(msg: T) -> Self {
486-
Self::new(Code::InvalidArgument, msg.to_string())
487-
}
488-
}
489-
490-
// Allows for mapping this type into a generic deserialization error.
491-
impl serde::de::Error for Error {
492-
fn custom<T: std::fmt::Display>(msg: T) -> Self {
493-
Self::new(Code::InvalidArgument, msg.to_string())
494-
}
495-
}

0 commit comments

Comments
 (0)