@@ -462,8 +462,24 @@ def _call_api_internal(
462
462
LOGGER .debug ("HTTP Status: %s" , response .status_code )
463
463
if response is None :
464
464
return None
465
- if response .status_code == api .expected_status :
465
+
466
+ # Reset `has_retried` flag if:
467
+ # - SDK already attempted a 401 token refresh (`has_retried = True`)
468
+ # - and the current response status code is NOT 401
469
+ #
470
+ # Real-world scenario:
471
+ # - First 401 triggers `_handle_401_token_refresh`, setting `has_retried = True`
472
+ # - If the next response is also 401 → SDK returns 401 (won’t retry again)
473
+ # - But if the next response is != 401 (e.g. 403), and `has_retried = True`,
474
+ # then we should reset `has_retried = False` so that future 401s can trigger a new token refresh.
475
+ if (
476
+ self ._401_tls .has_retried
477
+ and response .status_code
478
+ != ErrorCode .AUTHENTICATION_PASSTHROUGH .http_error_code
479
+ ):
466
480
self ._401_tls .has_retried = False
481
+
482
+ if response .status_code == api .expected_status :
467
483
try :
468
484
if (
469
485
response .content is None
@@ -562,10 +578,10 @@ def _call_api_internal(
562
578
)
563
579
except Exception as e :
564
580
LOGGER .debug (
565
- "Failed to impersonate user %s for 401 token refresh. Not retrying. Error: %s" ,
566
- self ._user_id ,
581
+ "API call failed after a successful 401 token refresh. Error details: %s" ,
567
582
e ,
568
583
)
584
+ raise
569
585
570
586
if error_code and error_message :
571
587
error = ERROR_CODE_FOR_HTTP_STATUS .get (
@@ -697,12 +713,31 @@ def _handle_401_token_refresh(
697
713
698
714
returns: HTTP response received after retrying the request with the refreshed token
699
715
"""
700
- new_token = self .impersonate .user (user_id = self ._user_id )
716
+ try :
717
+ new_token = self .impersonate .user (user_id = self ._user_id )
718
+ except Exception as e :
719
+ LOGGER .debug (
720
+ "Failed to impersonate user %s for 401 token refresh. Not retrying. Error: %s" ,
721
+ self ._user_id ,
722
+ e ,
723
+ )
724
+ raise
701
725
self .api_key = new_token
702
726
self ._401_tls .has_retried = True
703
727
params ["headers" ]["authorization" ] = f"Bearer { self .api_key } "
704
728
self ._request_params ["headers" ]["authorization" ] = f"Bearer { self .api_key } "
705
729
LOGGER .debug ("Successfully completed 401 automatic token refresh." )
730
+
731
+ # Adding a short delay after token refresh
732
+ # This helps ensure that when we fetch typedefs using the new token,
733
+ # the backend has fully recognized the token as valid.
734
+ # Without this delay, we occasionally get an empty response `[]` from the API,
735
+ # likely because the backend hasn’t fully propagated token validity yet.
736
+ import time
737
+
738
+ time .sleep (5 )
739
+
740
+ # Retry the API call with the new token
706
741
return self ._call_api_internal (
707
742
api ,
708
743
path ,
0 commit comments