Improve launch status UI and alert on SpaceDevs payload errors

This commit is contained in:
Edward Betts 2026-02-21 16:39:47 +00:00
parent 458dfc5136
commit 7a50ea6016
3 changed files with 78 additions and 7 deletions

View file

@ -247,9 +247,52 @@ def is_test_flight(launch: StrDict) -> bool:
def get_launch_by_slug(data: StrDict, slug: str) -> StrDict | None:
"""Find last update for space launch."""
return {item["slug"]: typing.cast(StrDict, item) for item in data["results"]}.get(
slug
results = data.get("results")
if not isinstance(results, list):
return None
by_slug: dict[str, StrDict] = {}
for item in results:
if not isinstance(item, dict):
continue
item_slug = item.get("slug")
if isinstance(item_slug, str):
by_slug[item_slug] = typing.cast(StrDict, item)
return by_slug.get(slug)
def send_thespacedevs_payload_alert(
config: flask.config.Config,
reason: str,
data: StrDict | None,
) -> None:
"""Alert admin when SpaceDevs update payload is missing expected fields."""
payload = data or {}
detail = payload.get("detail")
status_code = payload.get("status_code", payload.get("status"))
detail_text = detail if isinstance(detail, str) else ""
is_rate_limited = (
status_code == 429
or "rate" in detail_text.lower()
or "thrott" in detail_text.lower()
)
alert_type = "rate-limit" if is_rate_limited else "error"
subject = f"⚠️ SpaceDevs {alert_type}: {reason}"
body = f"""SpaceDevs update returned an unexpected payload.
Reason: {reason}
Type: {alert_type}
Status: {status_code!r}
Detail: {detail!r}
Payload keys: {sorted(payload.keys())}
Expected payload shape includes a top-level 'results' list.
Updater: /home/edward/src/agenda/update.py
"""
agenda.mail.send_mail(config, subject, body)
def update_thespacedevs(config: flask.config.Config) -> None:
@ -283,12 +326,26 @@ def update_thespacedevs(config: flask.config.Config) -> None:
t0 = time()
data = agenda.thespacedevs.next_launch_api_data(rocket_dir)
if not data:
send_thespacedevs_payload_alert(
config,
reason="API request failed or returned invalid JSON",
data=None,
)
return # thespacedevs API call failed
data_results = data.get("results")
if not isinstance(data_results, list):
send_thespacedevs_payload_alert(
config,
reason="response missing top-level results list",
data=data,
)
return
# Identify test-flight slugs present in the current data
cur_test_slugs: set[str] = {
typing.cast(str, item["slug"])
for item in data.get("results", [])
for item in data_results
if is_test_flight(typing.cast(StrDict, item))
}
@ -317,7 +374,7 @@ def update_thespacedevs(config: flask.config.Config) -> None:
time_taken = time() - t0
if not sys.stdin.isatty():
return
rockets = [agenda.thespacedevs.summarize_launch(item) for item in data["results"]]
rockets = [agenda.thespacedevs.summarize_launch(item) for item in data_results]
print(len(rockets), "launches")
print(len(active_crewed or []), "active crewed missions")
print(f"took {time_taken:.1f} seconds")