@@ -36,7 +36,7 @@ def request(
3636 method : HttpMethod ,
3737 url : str ,
3838 headers : Optional [Dict [str , str ]] = None ,
39- ** kwargs
39+ ** kwargs ,
4040 ) -> BaseHTTPResponse :
4141 """Make an HTTP request."""
4242 pass
@@ -60,7 +60,7 @@ def request(
6060 method : HttpMethod ,
6161 url : str ,
6262 headers : Optional [Dict [str , str ]] = None ,
63- ** kwargs
63+ ** kwargs ,
6464 ) -> BaseHTTPResponse :
6565 """Make an HTTP request using the underlying HTTP client."""
6666 return self ._http_client .request (method , url , headers , ** kwargs )
@@ -91,10 +91,11 @@ def __init__(self, delegate: ITelemetryPushClient, host: str):
9191 def _create_mock_success_response (self ) -> BaseHTTPResponse :
9292 """
9393 Create a mock success response for when circuit breaker is open.
94-
94+
9595 This allows telemetry to fail silently without raising exceptions.
9696 """
9797 from unittest .mock import Mock
98+
9899 mock_response = Mock (spec = BaseHTTPResponse )
99100 mock_response .status = 200
100101 mock_response .data = b'{"numProtoSuccess": 0, "errors": []}'
@@ -105,77 +106,81 @@ def request(
105106 method : HttpMethod ,
106107 url : str ,
107108 headers : Optional [Dict [str , str ]] = None ,
108- ** kwargs
109+ ** kwargs ,
109110 ) -> BaseHTTPResponse :
110111 """
111112 Make an HTTP request with circuit breaker protection.
112-
113+
113114 Circuit breaker only opens for 429/503 responses (rate limiting).
114115 If circuit breaker is open, silently drops the telemetry request.
115116 Other errors fail silently without triggering circuit breaker.
116117 """
117-
118+
118119 def _make_request_and_check_status ():
119120 """
120121 Inner function that makes the request and checks response status.
121-
122+
122123 Raises TelemetryRateLimitError ONLY for 429/503 so circuit breaker counts them as failures.
123124 For all other errors, returns mock success response so circuit breaker does NOT count them.
124-
125+
125126 This ensures circuit breaker only opens for rate limiting, not for network errors,
126127 timeouts, or server errors.
127128 """
128129 try :
129130 response = self ._delegate .request (method , url , headers , ** kwargs )
130-
131+
131132 # Check for rate limiting or service unavailable in successful response
132133 # (case where urllib3 returns response without exhausting retries)
133134 if response .status in [429 , 503 ]:
134135 logger .warning (
135136 "Telemetry endpoint returned %d for host %s, triggering circuit breaker" ,
136137 response .status ,
137- self ._host
138+ self ._host ,
138139 )
139140 raise TelemetryRateLimitError (
140141 f"Telemetry endpoint rate limited or unavailable: { response .status } "
141142 )
142-
143+
143144 return response
144-
145+
145146 except Exception as e :
146147 # Don't catch TelemetryRateLimitError - let it propagate to circuit breaker
147148 if isinstance (e , TelemetryRateLimitError ):
148149 raise
149-
150+
150151 # Check if it's a RequestError with rate limiting status code (exhausted retries)
151152 if isinstance (e , RequestError ):
152- http_code = e .context .get ("http-code" ) if hasattr (e , "context" ) and e .context else None
153-
153+ http_code = (
154+ e .context .get ("http-code" )
155+ if hasattr (e , "context" ) and e .context
156+ else None
157+ )
158+
154159 if http_code in [429 , 503 ]:
155160 logger .warning (
156161 "Telemetry retries exhausted with status %d for host %s, triggering circuit breaker" ,
157162 http_code ,
158- self ._host
163+ self ._host ,
159164 )
160165 raise TelemetryRateLimitError (
161166 f"Telemetry rate limited after retries: { http_code } "
162167 )
163-
168+
164169 # NOT rate limiting (500 errors, network errors, timeouts, etc.)
165170 # Return mock success response so circuit breaker does NOT see this as a failure
166171 logger .debug (
167172 "Non-rate-limit telemetry error for host %s: %s, failing silently" ,
168173 self ._host ,
169- e
174+ e ,
170175 )
171176 return self ._create_mock_success_response ()
172-
177+
173178 try :
174179 # Use circuit breaker to protect the request
175180 # The inner function will raise TelemetryRateLimitError for 429/503
176181 # which the circuit breaker will count as a failure
177182 return self ._circuit_breaker .call (_make_request_and_check_status )
178-
183+
179184 except Exception as e :
180185 # All telemetry errors are consumed and return mock success
181186 # Log appropriate message based on exception type
@@ -188,10 +193,13 @@ def _make_request_and_check_status():
188193 logger .debug (
189194 "Telemetry rate limited for host %s (already counted by circuit breaker): %s" ,
190195 self ._host ,
191- e
196+ e ,
192197 )
193198 else :
194- logger .debug ("Unexpected telemetry error for host %s: %s, failing silently" , self ._host , e )
195-
196- return self ._create_mock_success_response ()
199+ logger .debug (
200+ "Unexpected telemetry error for host %s: %s, failing silently" ,
201+ self ._host ,
202+ e ,
203+ )
197204
205+ return self ._create_mock_success_response ()
0 commit comments