@@ -19,6 +19,8 @@ use nativelink_metric::{
1919} ;
2020use prost_types:: TimestampError ;
2121use 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]
2426macro_rules! make_err {
@@ -48,6 +50,7 @@ macro_rules! error_if {
4850
4951#[ derive( Debug , Eq , PartialEq , Clone , Serialize , Deserialize ) ]
5052pub 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-
194191impl 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 {
207204impl 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-
222213impl 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-
251236impl 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
257242impl 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