fix(unraid): expose sanitized inference error detail
This commit is contained in:
@@ -41,6 +41,7 @@ class State:
|
|||||||
self.inference_fault = False
|
self.inference_fault = False
|
||||||
self.ws_source_ok = False
|
self.ws_source_ok = False
|
||||||
self.error_code: str | None = None
|
self.error_code: str | None = None
|
||||||
|
self.error_detail: str | None = None
|
||||||
self.frame_id = 0
|
self.frame_id = 0
|
||||||
self.messages = 0
|
self.messages = 0
|
||||||
self.frames_dropped = 0
|
self.frames_dropped = 0
|
||||||
@@ -97,7 +98,8 @@ def health():
|
|||||||
"last_frame_age_ms": round(age, 3) if age is not None else None,
|
"last_frame_age_ms": round(age, 3) if age is not None else None,
|
||||||
"actual_width": state.width or None, "actual_height": state.height or None},
|
"actual_width": state.width or None, "actual_height": state.height or None},
|
||||||
"models": {"detector_ready": state.models_ready, "pose_ready": state.models_ready},
|
"models": {"detector_ready": state.models_ready, "pose_ready": state.models_ready},
|
||||||
"error_code": state.error_code, "uptime_seconds": round(time.monotonic() - state.started, 1)}
|
"error_code": state.error_code, "error_detail": state.error_detail,
|
||||||
|
"uptime_seconds": round(time.monotonic() - state.started, 1)}
|
||||||
|
|
||||||
|
|
||||||
@app.get("/v1/capabilities", dependencies=[Depends(authorized)])
|
@app.get("/v1/capabilities", dependencies=[Depends(authorized)])
|
||||||
@@ -144,14 +146,16 @@ def inference_worker(loop: asyncio.AbstractEventLoop) -> None:
|
|||||||
threshold = float(os.getenv("DETECTION_THRESHOLD", ".35")); max_people = int(os.getenv("MAX_PEOPLE", "4"))
|
threshold = float(os.getenv("DETECTION_THRESHOLD", ".35")); max_people = int(os.getenv("MAX_PEOPLE", "4"))
|
||||||
try:
|
try:
|
||||||
models.load(); state.models_ready = True; LOG.info("official detector and pose checkpoints loaded")
|
models.load(); state.models_ready = True; LOG.info("official detector and pose checkpoints loaded")
|
||||||
except Exception:
|
except Exception as exc:
|
||||||
state.inference_fault = True; state.error_code = "MODEL_LOAD_FAILED"; LOG.exception("model loading failed"); return
|
state.inference_fault = True; state.error_code = "MODEL_LOAD_FAILED"
|
||||||
|
state.error_detail = f"{type(exc).__name__}: {str(exc)[:240]}"; LOG.exception("model loading failed"); return
|
||||||
while True:
|
while True:
|
||||||
frame = frames.get(); started_ns = time.time_ns(); perf = time.perf_counter_ns()
|
frame = frames.get(); started_ns = time.time_ns(); perf = time.perf_counter_ns()
|
||||||
try:
|
try:
|
||||||
people, det_ms, pose_ms = models.infer(frame.pixels, threshold, max_people)
|
people, det_ms, pose_ms = models.infer(frame.pixels, threshold, max_people)
|
||||||
finished_ns = time.time_ns(); total_ms = (time.perf_counter_ns() - perf) / 1e6
|
finished_ns = time.time_ns(); total_ms = (time.perf_counter_ns() - perf) / 1e6
|
||||||
state.frame_id += 1; state.cuda_inference_ok = True; state.inference_fault = False; state.error_code = None
|
state.frame_id += 1; state.cuda_inference_ok = True; state.inference_fault = False
|
||||||
|
state.error_code = None; state.error_detail = None
|
||||||
msg = {"schema": "tail2.pose.v1", "stream_id": config["stream_id"], "session_id": state.session_id,
|
msg = {"schema": "tail2.pose.v1", "stream_id": config["stream_id"], "session_id": state.session_id,
|
||||||
"frame_id": state.frame_id, "source_received_unix_ns": frame.received_ns,
|
"frame_id": state.frame_id, "source_received_unix_ns": frame.received_ns,
|
||||||
"inference_started_unix_ns": started_ns, "inference_finished_unix_ns": finished_ns,
|
"inference_started_unix_ns": started_ns, "inference_finished_unix_ns": finished_ns,
|
||||||
@@ -164,8 +168,9 @@ def inference_worker(loop: asyncio.AbstractEventLoop) -> None:
|
|||||||
"error": None}
|
"error": None}
|
||||||
state.inference_ms.append(total_ms); state.messages += 1; state.ws_source_ok = True
|
state.inference_ms.append(total_ms); state.messages += 1; state.ws_source_ok = True
|
||||||
hub.publish_on_loop(loop, msg)
|
hub.publish_on_loop(loop, msg)
|
||||||
except Exception:
|
except Exception as exc:
|
||||||
state.inference_fault = True; state.error_code = "INFERENCE_FAILED"; LOG.exception("inference failed")
|
state.inference_fault = True; state.error_code = "INFERENCE_FAILED"
|
||||||
|
state.error_detail = f"{type(exc).__name__}: {str(exc)[:240]}"; LOG.exception("inference failed")
|
||||||
|
|
||||||
|
|
||||||
@app.on_event("startup")
|
@app.on_event("startup")
|
||||||
@@ -178,4 +183,3 @@ async def startup() -> None:
|
|||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
uvicorn.run(app, host=os.getenv("API_BIND", "0.0.0.0"), port=int(os.getenv("API_PORT", "18120")),
|
uvicorn.run(app, host=os.getenv("API_BIND", "0.0.0.0"), port=int(os.getenv("API_PORT", "18120")),
|
||||||
access_log=False, ws_max_size=65536)
|
access_log=False, ws_max_size=65536)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user