fix(heartbeat): replace bare except Exception with specific types and intent comments

This commit is contained in:
2026-04-30 20:19:52 -04:00
parent 72498f81b2
commit c648d8b04e

View File

@@ -19,7 +19,7 @@ from datetime import datetime, timezone
from typing import Any, Optional
from fastapi import APIRouter, Depends, HTTPException, Request
from pydantic import BaseModel
from pydantic import BaseModel, ValidationError
from decnet.config import DeckyConfig
from decnet.logging import get_logger
@@ -60,7 +60,8 @@ def _extract_peer_fingerprint(scope: dict[str, Any]) -> Optional[str]:
if chain:
peer_der = chain[0]
source = "primary"
except Exception:
except (AttributeError, KeyError, TypeError):
# scope["extensions"]["tls"] structure varies across uvicorn versions
peer_der = None
if peer_der is None:
@@ -71,7 +72,8 @@ def _extract_peer_fingerprint(scope: dict[str, Any]) -> Optional[str]:
peer_der = ssl_obj.getpeercert(binary_form=True)
if peer_der:
source = "fallback"
except Exception:
except (AttributeError, OSError):
# transport may not be an SSL transport, or the handshake may be incomplete
peer_der = None
if not peer_der:
@@ -121,6 +123,7 @@ async def _reconcile_topology_report(
try:
topos = await repo.list_topologies(status=TopologyStatus.ACTIVE)
except Exception:
# Non-fatal: reconcile is best-effort; the host stays alive regardless
log.exception("heartbeat: could not list active topologies")
return
mine = [t for t in topos if t.get("target_host_uuid") == host_uuid]
@@ -139,6 +142,7 @@ async def _reconcile_topology_report(
try:
hydrated = await hydrate(repo, tid)
except Exception:
# Non-fatal: skip this topology; mutator reconcile loop will retry
log.exception("heartbeat: hydrate failed tid=%s", tid)
continue
if hydrated is None:
@@ -155,6 +159,7 @@ async def _reconcile_topology_report(
tid, host_uuid, reported_id, reported_hash, expected,
)
except Exception:
# Non-fatal: mutator reconcile loop will detect the mismatch again next heartbeat
log.exception("heartbeat: failed to flag resync tid=%s", tid)
@@ -192,7 +197,7 @@ async def heartbeat(
for decky_dict in status_body.get("deckies") or []:
try:
d = DeckyConfig(**decky_dict)
except Exception:
except (ValidationError, TypeError):
log.exception("heartbeat: skipping malformed decky payload host=%s", req.host_uuid)
continue
rstate = runtime.get(d.name) or {}