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,26 @@ 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
+ if self . 0 . len ( ) > 1 {
64
+ write ! ( f, "Multiple errors occured: " ) ?;
65
+ }
66
+ for err in & self . 0 {
67
+ if needs_comma {
68
+ write ! ( f, ", " ) ?;
69
+ }
70
+ needs_comma = true ;
71
+ write ! ( f, "{err}" ) ?;
72
+ }
73
+ Ok ( ( ) )
74
+ }
75
+ }
76
+
56
77
/// How to connect to a `Transport`
57
78
#[ async_trait]
58
79
trait ConnectionHandler {
@@ -470,6 +491,7 @@ where
470
491
let mut backoff = Backoff :: new ( backoff_config) ;
471
492
backoff
472
493
. retry_with_backoff ( "broker_connect" , || async {
494
+ let mut errors = Vec :: < Box < dyn std:: error:: Error + Send + Sync > > :: new ( ) ;
473
495
for broker in & brokers {
474
496
let conn = broker
475
497
. connect (
@@ -485,16 +507,14 @@ where
485
507
Ok ( transport) => transport,
486
508
Err ( e) => {
487
509
warn ! ( %e, "Failed to connect to broker" ) ;
510
+ errors. push ( Box :: new ( e) ) ;
488
511
continue ;
489
512
}
490
513
} ;
491
514
492
515
return ControlFlow :: Break ( connection) ;
493
516
}
494
-
495
- let err = Box :: < dyn std:: error:: Error + Send + Sync > :: from (
496
- "Failed to connect to any broker, backing off" . to_string ( ) ,
497
- ) ;
517
+ let err = Box :: < dyn std:: error:: Error + Send + Sync > :: from ( MultiError ( errors) ) ;
498
518
let err: Arc < dyn std:: error:: Error + Send + Sync > = err. into ( ) ;
499
519
ControlFlow :: Continue ( ErrorOrThrottle :: Error ( err) )
500
520
} )
0 commit comments