@@ -153,9 +153,11 @@ export class PickFirstLoadBalancer implements LoadBalancer {
153153 private subchannelStateListener : ConnectivityStateListener = (
154154 subchannel ,
155155 previousState ,
156- newState
156+ newState ,
157+ keepaliveTime ,
158+ errorMessage
157159 ) => {
158- this . onSubchannelStateUpdate ( subchannel , previousState , newState ) ;
160+ this . onSubchannelStateUpdate ( subchannel , previousState , newState , errorMessage ) ;
159161 } ;
160162 /**
161163 * Timer reference for the timer tracking when to start
@@ -172,6 +174,12 @@ export class PickFirstLoadBalancer implements LoadBalancer {
172174 */
173175 private stickyTransientFailureMode = false ;
174176
177+ /**
178+ * The most recent error reported by any subchannel as it transitioned to
179+ * TRANSIENT_FAILURE.
180+ */
181+ private lastError : string | null = null ;
182+
175183 /**
176184 * Load balancer that attempts to connect to each backend in the address list
177185 * in order, and picks the first one that connects, using it for every
@@ -200,7 +208,7 @@ export class PickFirstLoadBalancer implements LoadBalancer {
200208 if ( this . stickyTransientFailureMode ) {
201209 this . updateState (
202210 ConnectivityState . TRANSIENT_FAILURE ,
203- new UnavailablePicker ( )
211+ new UnavailablePicker ( { details : `No connection established. Last error: ${ this . lastError } ` } )
204212 ) ;
205213 } else {
206214 this . updateState ( ConnectivityState . CONNECTING , new QueuePicker ( this ) ) ;
@@ -241,7 +249,8 @@ export class PickFirstLoadBalancer implements LoadBalancer {
241249 private onSubchannelStateUpdate (
242250 subchannel : SubchannelInterface ,
243251 previousState : ConnectivityState ,
244- newState : ConnectivityState
252+ newState : ConnectivityState ,
253+ errorMessage ?: string
245254 ) {
246255 if ( this . currentPick ?. realSubchannelEquals ( subchannel ) ) {
247256 if ( newState !== ConnectivityState . READY ) {
@@ -258,6 +267,9 @@ export class PickFirstLoadBalancer implements LoadBalancer {
258267 }
259268 if ( newState === ConnectivityState . TRANSIENT_FAILURE ) {
260269 child . hasReportedTransientFailure = true ;
270+ if ( errorMessage ) {
271+ this . lastError = errorMessage ;
272+ }
261273 this . maybeEnterStickyTransientFailureMode ( ) ;
262274 if ( index === this . currentSubchannelIndex ) {
263275 this . startNextSubchannelConnecting ( index + 1 ) ;
0 commit comments