1
1
use async_trait:: async_trait;
2
2
use rand:: prelude:: * ;
3
+ use std:: fmt:: Display ;
3
4
use std:: ops:: ControlFlow ;
4
5
use std:: sync:: Arc ;
5
6
use thiserror:: Error ;
@@ -53,6 +54,23 @@ pub enum Error {
53
54
54
55
pub type Result < T , E = Error > = std:: result:: Result < T , E > ;
55
56
57
+ #[ derive( Debug , Error ) ]
58
+ pub struct MultiError ( Vec < Box < dyn std:: error:: Error + Send + Sync > > ) ;
59
+
60
+ impl Display for MultiError {
61
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
62
+ let mut needs_comma = false ;
63
+ for err in & self . 0 {
64
+ if needs_comma {
65
+ write ! ( f, ", " ) ?;
66
+ }
67
+ needs_comma = true ;
68
+ write ! ( f, "{err}" ) ?;
69
+ }
70
+ Ok ( ( ) )
71
+ }
72
+ }
73
+
56
74
/// How to connect to a `Transport`
57
75
#[ async_trait]
58
76
trait ConnectionHandler {
@@ -470,6 +488,7 @@ where
470
488
let mut backoff = Backoff :: new ( backoff_config) ;
471
489
backoff
472
490
. retry_with_backoff ( "broker_connect" , || async {
491
+ let mut errors = Vec :: < Box < dyn std:: error:: Error + Send + Sync > > :: new ( ) ;
473
492
for broker in & brokers {
474
493
let conn = broker
475
494
. connect (
@@ -485,16 +504,14 @@ where
485
504
Ok ( transport) => transport,
486
505
Err ( e) => {
487
506
warn ! ( %e, "Failed to connect to broker" ) ;
507
+ errors. push ( Box :: new ( e) ) ;
488
508
continue ;
489
509
}
490
510
} ;
491
511
492
512
return ControlFlow :: Break ( connection) ;
493
513
}
494
-
495
- let err = Box :: < dyn std:: error:: Error + Send + Sync > :: from (
496
- "Failed to connect to any broker, backing off" . to_string ( ) ,
497
- ) ;
514
+ let err = Box :: < dyn std:: error:: Error + Send + Sync > :: from ( MultiError ( errors) ) ;
498
515
let err: Arc < dyn std:: error:: Error + Send + Sync > = err. into ( ) ;
499
516
ControlFlow :: Continue ( ErrorOrThrottle :: Error ( err) )
500
517
} )
0 commit comments