@@ -19,6 +19,8 @@ use nativelink_metric::{
19
19
} ;
20
20
use prost_types:: TimestampError ;
21
21
use serde:: { Deserialize , Serialize } ;
22
+ // Reexport of tonic's error codes which we use as "nativelink_error::Code".
23
+ pub use tonic:: Code ;
22
24
23
25
#[ macro_export]
24
26
macro_rules! make_err {
@@ -48,6 +50,7 @@ macro_rules! error_if {
48
50
49
51
#[ derive( Debug , Eq , PartialEq , Clone , Serialize , Deserialize ) ]
50
52
pub struct Error {
53
+ #[ serde( with = "CodeDef" ) ]
51
54
pub code : Code ,
52
55
pub messages : Vec < String > ,
53
56
}
@@ -105,7 +108,7 @@ impl Error {
105
108
}
106
109
107
110
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 ( " : " ) )
109
112
}
110
113
111
114
pub fn message_string ( & self ) -> String {
@@ -185,12 +188,6 @@ impl From<std::num::ParseIntError> for Error {
185
188
}
186
189
}
187
190
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
-
194
191
impl From < std:: convert:: Infallible > for Error {
195
192
fn from ( _err : std:: convert:: Infallible ) -> Self {
196
193
// Infallible is an error type that can never happen.
@@ -207,18 +204,12 @@ impl From<TimestampError> for Error {
207
204
impl From < std:: io:: Error > for Error {
208
205
fn from ( err : std:: io:: Error ) -> Self {
209
206
Self {
210
- code : err. kind ( ) . into ( ) ,
207
+ code : err. kind ( ) . into_code ( ) ,
211
208
messages : vec ! [ err. to_string( ) ] ,
212
209
}
213
210
}
214
211
}
215
212
216
- impl From < Code > for Error {
217
- fn from ( code : Code ) -> Self {
218
- make_err ! ( code, "" )
219
- }
220
- }
221
-
222
213
impl From < fred:: error:: Error > for Error {
223
214
fn from ( error : fred:: error:: Error ) -> Self {
224
215
use fred:: error:: ErrorKind :: {
@@ -242,21 +233,15 @@ impl From<fred::error::Error> for Error {
242
233
}
243
234
}
244
235
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
-
251
236
impl From < tonic:: Status > for Error {
252
237
fn from ( status : tonic:: Status ) -> Self {
253
- make_err ! ( status. code( ) . into ( ) , "{}" , status. to_string( ) )
238
+ make_err ! ( status. code( ) , "{}" , status. to_string( ) )
254
239
}
255
240
}
256
241
257
242
impl From < Error > for tonic:: Status {
258
243
fn from ( val : Error ) -> Self {
259
- Self :: new ( val. code . into ( ) , val. messages . join ( " : " ) )
244
+ Self :: new ( val. code , val. messages . join ( " : " ) )
260
245
}
261
246
}
262
247
@@ -341,9 +326,58 @@ impl<T> ResultExt<T> for Option<T> {
341
326
}
342
327
}
343
328
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 {
347
381
Ok = 0 ,
348
382
Cancelled = 1 ,
349
383
Unknown = 2 ,
@@ -364,132 +398,3 @@ pub enum Code {
364
398
// NOTE: Additional codes must be added to stores.rs in ErrorCodes and also
365
399
// in both match statements in retry.rs.
366
400
}
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