Skip to content

Commit 00f9a4f

Browse files
chore: improve metadata service error handling (#1902)
Improved error handling in `google/auth/compute_engine/_metadata.py` to provide more informative error messages when retries are exhausted. The logic now handles two distinct failure modes: 1. **Connection Errors (Exceptions):** - Exceptions caught during the request (e.g., connection refused) are stored in `last_exception`. - If the retry loop exhausts and `last_exception` is set, a `TransportError` is raised that chains the original exception. This preserves the stack trace and specific error type for debugging. 2. **Retryable HTTP Status Codes:** - If a request completes but returns a retryable status code (e.g., 500, 503), `last_exception` is cleared (set to `None`). - If the retry loop exhausts due to repeated retryable status codes, a `TransportError` is raised that includes the `response.status` and the response body (`error_details`). This ensures the specific server error message is visible. This addresses feedback from PR 1637 by ensuring that "Ran out of retries" scenarios provide the most relevant context: either the underlying exception or the final HTTP error response. --- *PR created automatically by Jules for task [6226991344715693997](https://jules.google.com/task/6226991344715693997) started by @chalmerlowe* --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: Chalmer Lowe <chalmerlowe@google.com>
1 parent 5d00147 commit 00f9a4f

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)