Skip to content

Commit 9501f27

Browse files
chore: improve metadata service error handling
Distinguish between retry exhaustion due to exceptions and retry exhaustion due to retryable status codes. - Use `last_exception` to track the most recent exception. - Clear `last_exception` on successful response (even if status is retryable). - Raise TransportError chained from `last_exception` if available. - Otherwise raise TransportError with response status and details. - Update tests to match new error format.
1 parent 1406f44 commit 9501f27

File tree

2 files changed

+24
-14
lines changed

2 files changed

+24
-14
lines changed

google/auth/compute_engine/_metadata.py

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ def get(
294294
url = _helpers.update_query(base_url, query_params)
295295

296296
backoff = ExponentialBackoff(total_attempts=retry_count)
297-
failure_reason = None
297+
last_exception = None
298298
for attempt in backoff:
299299
try:
300300
response = request(
@@ -308,13 +308,10 @@ def get(
308308
retry_count,
309309
response.status,
310310
)
311-
failure_reason = (
312-
response.data.decode("utf-8")
313-
if hasattr(response.data, "decode")
314-
else response.data
315-
)
311+
last_exception = None
316312
continue
317313
else:
314+
last_exception = None
318315
break
319316

320317
except exceptions.TransportError as e:
@@ -325,14 +322,27 @@ def get(
325322
retry_count,
326323
e,
327324
)
328-
failure_reason = e
325+
last_exception = e
329326
else:
330-
raise exceptions.TransportError(
331-
"Failed to retrieve {} from the Google Compute Engine "
332-
"metadata service. Compute Engine Metadata server unavailable due to {}".format(
333-
url, failure_reason
327+
if last_exception:
328+
raise exceptions.TransportError(
329+
"Failed to retrieve {} from the Google Compute Engine "
330+
"metadata service. Compute Engine Metadata server unavailable. "
331+
"Last exception: {}".format(url, last_exception)
332+
) from last_exception
333+
else:
334+
error_details = (
335+
response.data.decode("utf-8")
336+
if hasattr(response.data, "decode")
337+
else response.data
338+
)
339+
raise exceptions.TransportError(
340+
"Failed to retrieve {} from the Google Compute Engine "
341+
"metadata service. Compute Engine Metadata server unavailable. "
342+
"Response status: {}\nResponse details:\n{}".format(
343+
url, response.status, error_details
344+
)
334345
)
335-
)
336346

337347
content = _helpers.from_bytes(response.data)
338348

tests/compute_engine/test__metadata.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ def test_get_failure_connection_failed(mock_sleep):
407407
_metadata.get(request, PATH)
408408

409409
assert excinfo.match(
410-
r"Compute Engine Metadata server unavailable due to failure message"
410+
r"Compute Engine Metadata server unavailable. Last exception: failure message"
411411
)
412412

413413
request.assert_called_with(
@@ -426,7 +426,7 @@ def test_get_too_many_requests_retryable_error_failure():
426426
_metadata.get(request, PATH)
427427

428428
assert excinfo.match(
429-
r"Compute Engine Metadata server unavailable due to too many requests"
429+
r"Compute Engine Metadata server unavailable. Response status: 429\nResponse details:\ntoo many requests"
430430
)
431431

432432
request.assert_called_with(

0 commit comments

Comments
 (0)