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