Files
stackpilot/backend/routers/dashboard.py
T
menzeljandClaude Opus 4.8 d399caadc9 Dashboard: surface the real compute_fleet error in the response (0.38.2)
The fleet endpoint returned a bare 500, so the error banner only showed
"status code 500" with no cause. Wrap the call to log the full traceback
server-side and return the exception type, message and originating
file:line in the HTTP detail, so the dashboard banner pinpoints the
failure for an authenticated user.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 11:31:19 +00:00

40 lines
1.4 KiB
Python

"""Dashboard aggregation endpoint (fleet-wide cockpit data)."""
from __future__ import annotations
import logging
import traceback
from fastapi import APIRouter, Depends, HTTPException
from sqlmodel import Session
from auth import get_current_user
from database import get_session
from models.user import User
from services import dashboard_service
logger = logging.getLogger("stackpilot.dashboard")
router = APIRouter(prefix="/api/dashboard", tags=["dashboard"])
@router.get("/fleet")
async def fleet(
refresh: bool = False,
session: Session = Depends(get_session),
_user: User = Depends(get_current_user),
) -> dict:
"""Fleet-wide 'needs attention' list, KPIs and per-host rollup across the
local host and every agent — the data behind the operator cockpit."""
try:
return await dashboard_service.compute_fleet(session, refresh=refresh)
except Exception as exc: # noqa: BLE001 — surface the real cause for diagnosis
logger.exception("compute_fleet failed")
# Deepest frame pinpoints where it broke; safe to expose to the
# authenticated user and it makes the dashboard error banner actionable.
tb = traceback.extract_tb(exc.__traceback__)
where = f" at {tb[-1].filename.split('/')[-1]}:{tb[-1].lineno}" if tb else ""
raise HTTPException(
status_code=500,
detail=f"{type(exc).__name__}: {exc}{where}",
) from exc