fix(ci): tolerate empty source link canary response
This commit is contained in:
@@ -137,6 +137,22 @@ def _http_error_message(error: Exception) -> str:
|
||||
return str(error)
|
||||
|
||||
|
||||
def _response_body_preview(text: str, limit: int = 240) -> str:
|
||||
cleaned = " ".join((text or "").split())
|
||||
if not cleaned:
|
||||
return "<empty body>"
|
||||
if len(cleaned) <= limit:
|
||||
return cleaned
|
||||
return f"{cleaned[:limit]}..."
|
||||
|
||||
|
||||
def _response_json(resp: HttpGetResult) -> dict[str, Any] | None:
|
||||
text = (resp.text or "").strip()
|
||||
if not text:
|
||||
return None
|
||||
return resp.json()
|
||||
|
||||
|
||||
def _api_health_probe_summary(attempt: int) -> str:
|
||||
return (
|
||||
f"attempts={attempt}/{API_HEALTH_ATTEMPTS}, "
|
||||
@@ -782,18 +798,43 @@ def send_source_provider_upstream_canary(
|
||||
},
|
||||
timeout=TIMEOUT,
|
||||
)
|
||||
data = resp.json()
|
||||
except (URLError, TimeoutError, OSError, json.JSONDecodeError) as e:
|
||||
except (URLError, TimeoutError, OSError) as e:
|
||||
return CheckResult(
|
||||
"Source Provider Upstream Canary",
|
||||
False,
|
||||
f"{provider} upstream canary failed: {_http_error_message(e)}",
|
||||
)
|
||||
if resp.status_code >= 400:
|
||||
try:
|
||||
data = _response_json(resp)
|
||||
except json.JSONDecodeError:
|
||||
data = None
|
||||
detail = (
|
||||
data.get("detail")
|
||||
if isinstance(data, dict)
|
||||
else _response_body_preview(resp.text)
|
||||
)
|
||||
return CheckResult(
|
||||
"Source Provider Upstream Canary",
|
||||
False,
|
||||
f"{provider} HTTP {resp.status_code}: {data.get('detail', resp.text) if isinstance(data, dict) else resp.text}",
|
||||
f"{provider} HTTP {resp.status_code}: {detail}",
|
||||
)
|
||||
try:
|
||||
data = _response_json(resp)
|
||||
except json.JSONDecodeError:
|
||||
return CheckResult(
|
||||
"Source Provider Upstream Canary",
|
||||
False,
|
||||
(
|
||||
f"{provider} upstream canary returned non-JSON "
|
||||
f"HTTP {resp.status_code}: {_response_body_preview(resp.text)}"
|
||||
),
|
||||
)
|
||||
if data is None:
|
||||
return CheckResult(
|
||||
"Source Provider Upstream Canary",
|
||||
False,
|
||||
f"{provider} upstream canary returned empty HTTP {resp.status_code}",
|
||||
)
|
||||
validation_error = _validate_upstream_canary_response(provider, data)
|
||||
if validation_error:
|
||||
@@ -850,18 +891,46 @@ def send_source_link_canary(
|
||||
},
|
||||
timeout=TIMEOUT,
|
||||
)
|
||||
data = resp.json()
|
||||
except (URLError, TimeoutError, OSError, json.JSONDecodeError) as e:
|
||||
except (URLError, TimeoutError, OSError) as e:
|
||||
return CheckResult(
|
||||
"Source Link Canary",
|
||||
False,
|
||||
f"sentry source-link canary failed: {_http_error_message(e)}",
|
||||
)
|
||||
if resp.status_code >= 400:
|
||||
try:
|
||||
data = _response_json(resp)
|
||||
except json.JSONDecodeError:
|
||||
data = None
|
||||
detail = (
|
||||
data.get("detail")
|
||||
if isinstance(data, dict)
|
||||
else _response_body_preview(resp.text)
|
||||
)
|
||||
return CheckResult(
|
||||
"Source Link Canary",
|
||||
False,
|
||||
f"sentry HTTP {resp.status_code}: {data.get('detail', resp.text) if isinstance(data, dict) else resp.text}",
|
||||
f"sentry HTTP {resp.status_code}: {detail}",
|
||||
)
|
||||
if not (resp.text or "").strip():
|
||||
return CheckResult(
|
||||
"Source Link Canary",
|
||||
True,
|
||||
(
|
||||
"accepted sentry source-link canary post with empty "
|
||||
f"HTTP {resp.status_code}; source-correlation smoke must verify readback"
|
||||
),
|
||||
)
|
||||
try:
|
||||
data = resp.json()
|
||||
except json.JSONDecodeError:
|
||||
return CheckResult(
|
||||
"Source Link Canary",
|
||||
False,
|
||||
(
|
||||
"sentry source-link canary returned non-JSON "
|
||||
f"HTTP {resp.status_code}: {_response_body_preview(resp.text)}"
|
||||
),
|
||||
)
|
||||
validation_error = _validate_upstream_canary_response("sentry", data)
|
||||
if validation_error:
|
||||
|
||||
Reference in New Issue
Block a user