@@ -182,7 +182,7 @@ private async Task AuthenticateAsync()
182182 // Trailers are only readable once the call has completed. Reading them
183183 // eagerly throws InvalidOperationException on a handshake that failed,
184184 // which masks the gRPC status that says what actually went wrong.
185- RpcException ? failure = null ;
185+ Exception ? failure = null ;
186186 var token = headers . Get ( "authorization" ) ;
187187 if ( token == null )
188188 {
@@ -191,9 +191,7 @@ private async Task AuthenticateAsync()
191191
192192 if ( token == null || _httpClient == null )
193193 {
194- var reason = failure == null
195- ? "the runtime returned no authorization token."
196- : DescribeRpcFailure ( failure ) ;
194+ var reason = DescribeAuthFailure ( failure ) ;
197195
198196 throw new SpiceException (
199197 SpiceStatus . FailedToAuthenticate ,
@@ -209,11 +207,11 @@ private async Task AuthenticateAsync()
209207 /// completed far enough for them to be available.
210208 /// </summary>
211209 /// <param name="stream">The handshake call</param>
212- /// <param name="failure">The gRPC failure, when the trailers could not be read </param>
210+ /// <param name="failure">The failure that prevented reading the trailers, if any </param>
213211 /// <returns>The token entry, or null</returns>
214- private static Metadata . Entry ? TryGetTrailerToken (
212+ internal static Metadata . Entry ? TryGetTrailerToken (
215213 AsyncDuplexStreamingCall < FlightHandshakeRequest , FlightHandshakeResponse > stream ,
216- out RpcException ? failure )
214+ out Exception ? failure )
217215 {
218216 failure = null ;
219217 try
@@ -225,9 +223,10 @@ private async Task AuthenticateAsync()
225223 failure = ex ;
226224 return null ;
227225 }
228- catch ( InvalidOperationException )
226+ catch ( InvalidOperationException ex )
229227 {
230228 // The handshake never completed, so there are no trailers to read.
229+ failure = ex ;
231230 return null ;
232231 }
233232 }
@@ -243,6 +242,21 @@ private static string DescribeRpcFailure(RpcException ex)
243242 return $ "{ ex . StatusCode } - { detail } .";
244243 }
245244
245+ /// <summary>
246+ /// Renders why the auth token could not be obtained as something a caller can act on.
247+ /// </summary>
248+ /// <param name="failure">The failure captured while trying to read the token, if any</param>
249+ /// <returns>A short description of the failure</returns>
250+ internal static string DescribeAuthFailure ( Exception ? failure )
251+ {
252+ return failure switch
253+ {
254+ null => "the runtime returned no authorization token." ,
255+ RpcException rpcEx => DescribeRpcFailure ( rpcEx ) ,
256+ _ => "the handshake did not complete before trailers could be read."
257+ } ;
258+ }
259+
246260 internal async Task < FlightClientRecordBatchStreamReader > Query ( string sql )
247261 {
248262 if ( string . IsNullOrEmpty ( sql ) )
0 commit comments