From ea1e383cfc7011b78d0b3d4bdffe65a86aec69ac Mon Sep 17 00:00:00 2001 From: Martin Hohenberg Date: Thu, 18 Jun 2026 21:38:40 +0200 Subject: [PATCH] Fix logging and surface unhandled exceptions - basicConfig so the pops logger actually emits output - Global exception handler logs full traceback + returns detail in 500 Co-Authored-By: Claude Sonnet 4.6 --- app/main.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/app/main.py b/app/main.py index f8a1dc8..fda4b98 100644 --- a/app/main.py +++ b/app/main.py @@ -1,12 +1,17 @@ import logging from contextlib import asynccontextmanager -from fastapi import FastAPI +from fastapi import FastAPI, Request +from fastapi.responses import JSONResponse from app.db import check_db, run_migrations from app.routers import filaments, pricing, print_jobs, printers, todos from app.routers import ui +logging.basicConfig( + level=logging.INFO, + format="%(asctime)s %(levelname)-8s %(name)s: %(message)s", +) logger = logging.getLogger("pops") @@ -18,7 +23,7 @@ async def lifespan(app: FastAPI): try: run_migrations() except Exception: - logger.exception("Migration failed — app will start but DB schema may be out of date") + logger.exception("Migration failed — schema may be out of date") else: logger.warning("Database unreachable: %s", msg) yield @@ -26,6 +31,13 @@ async def lifespan(app: FastAPI): app = FastAPI(title="POPS", lifespan=lifespan) + +@app.exception_handler(Exception) +async def unhandled_exception(request: Request, exc: Exception): + logger.exception("Unhandled error on %s %s", request.method, request.url) + return JSONResponse(status_code=500, content={"detail": str(exc)}) + + # JSON API app.include_router(printers.router, prefix="/api") app.include_router(filaments.router, prefix="/api") @@ -33,7 +45,7 @@ app.include_router(print_jobs.router, prefix="/api") app.include_router(todos.router, prefix="/api") app.include_router(pricing.router, prefix="/api") -# Web UI (must come after API to avoid route shadowing) +# Web UI app.include_router(ui.router)