Claude
commited on
fix(api): validate case_id and log volume computation errors (BUG-011, BUG-012)
Browse filesBUG-011: Replace bare exception suppression with proper logging
- Log expected errors (FileNotFoundError, ValueError) at warning level
- Log unexpected errors with full traceback for debugging
- Remove unused contextlib import
BUG-012: Validate case_id before creating job
- Check case_id exists in dataset before job creation
- Return 400 immediately for invalid case IDs
- Prevents confusing failures after 30+ seconds of processing
src/stroke_deepisles_demo/api/routes.py
CHANGED
|
@@ -10,7 +10,6 @@ This pattern avoids HuggingFace Spaces' ~60s gateway timeout.
|
|
| 10 |
|
| 11 |
from __future__ import annotations
|
| 12 |
|
| 13 |
-
import contextlib
|
| 14 |
import os
|
| 15 |
import uuid
|
| 16 |
from pathlib import Path
|
|
@@ -94,6 +93,14 @@ def create_segment_job(
|
|
| 94 |
- Returning immediately avoids timeout errors
|
| 95 |
"""
|
| 96 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
# Use full UUID hex for uniqueness (no truncation)
|
| 98 |
job_id = uuid.uuid4().hex
|
| 99 |
store = get_job_store()
|
|
@@ -225,10 +232,16 @@ def run_segmentation_job(
|
|
| 225 |
|
| 226 |
store.update_progress(job_id, 85, "Computing metrics...")
|
| 227 |
|
| 228 |
-
# Compute volume
|
| 229 |
volume_ml = None
|
| 230 |
-
|
| 231 |
volume_ml = round(compute_volume_ml(result.prediction_mask, threshold=0.5), 2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 232 |
|
| 233 |
store.update_progress(job_id, 95, "Preparing results...")
|
| 234 |
|
|
|
|
| 10 |
|
| 11 |
from __future__ import annotations
|
| 12 |
|
|
|
|
| 13 |
import os
|
| 14 |
import uuid
|
| 15 |
from pathlib import Path
|
|
|
|
| 93 |
- Returning immediately avoids timeout errors
|
| 94 |
"""
|
| 95 |
try:
|
| 96 |
+
# Validate case_id exists before creating job (BUG-012 fix)
|
| 97 |
+
valid_cases = list_case_ids()
|
| 98 |
+
if body.case_id not in valid_cases:
|
| 99 |
+
raise HTTPException(
|
| 100 |
+
status_code=400,
|
| 101 |
+
detail=f"Invalid case ID: '{body.case_id}'. Use GET /api/cases for available cases.",
|
| 102 |
+
)
|
| 103 |
+
|
| 104 |
# Use full UUID hex for uniqueness (no truncation)
|
| 105 |
job_id = uuid.uuid4().hex
|
| 106 |
store = get_job_store()
|
|
|
|
| 232 |
|
| 233 |
store.update_progress(job_id, 85, "Computing metrics...")
|
| 234 |
|
| 235 |
+
# Compute volume - log failures but don't crash the job (BUG-011 fix)
|
| 236 |
volume_ml = None
|
| 237 |
+
try:
|
| 238 |
volume_ml = round(compute_volume_ml(result.prediction_mask, threshold=0.5), 2)
|
| 239 |
+
except (FileNotFoundError, ValueError) as e:
|
| 240 |
+
# Expected failures: missing mask file or invalid threshold
|
| 241 |
+
logger.warning("Could not compute volume for job %s: %s", job_id, e)
|
| 242 |
+
except Exception:
|
| 243 |
+
# Unexpected failures - log full traceback for debugging
|
| 244 |
+
logger.exception("Unexpected error computing volume for job %s", job_id)
|
| 245 |
|
| 246 |
store.update_progress(job_id, 95, "Preparing results...")
|
| 247 |
|