fix: prevent app crash when frontend build is missing
StaticFiles defaults to check_dir=True, which raises at import time if frontend/dist/assets is missing on restart — taking down /healthz and /auth/* along with the frontend. Pass check_dir=False so the mount never crashes the app, and make the SPA fallback return a clear 503 instead of an unhandled 500 when index.html is absent. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013PphXq1s43DNRj1uWKGXof
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI, HTTPException
|
||||||
from fastapi.responses import FileResponse
|
from fastapi.responses import FileResponse
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
|
|
||||||
@@ -28,9 +28,19 @@ async def healthz():
|
|||||||
return {"status": "ok"}
|
return {"status": "ok"}
|
||||||
|
|
||||||
|
|
||||||
app.mount("/assets", StaticFiles(directory=FRONTEND_DIST / "assets"), name="frontend-assets")
|
app.mount(
|
||||||
|
"/assets",
|
||||||
|
StaticFiles(directory=FRONTEND_DIST / "assets", check_dir=False),
|
||||||
|
name="frontend-assets",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/{full_path:path}")
|
@app.get("/{full_path:path}")
|
||||||
async def serve_spa(full_path: str):
|
async def serve_spa(full_path: str):
|
||||||
return FileResponse(FRONTEND_DIST / "index.html")
|
index_file = FRONTEND_DIST / "index.html"
|
||||||
|
if not index_file.exists():
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=503,
|
||||||
|
detail="Frontend not built. Run `npm run build` in frontend/ and restart.",
|
||||||
|
)
|
||||||
|
return FileResponse(index_file)
|
||||||
|
|||||||
@@ -14,3 +14,13 @@ async def test_auth_routes_still_work_alongside_spa_fallback(client):
|
|||||||
"/auth/register", json={"username": "frontendcheck", "password": "spookyspooky"}
|
"/auth/register", json={"username": "frontendcheck", "password": "spookyspooky"}
|
||||||
)
|
)
|
||||||
assert response.status_code == 201
|
assert response.status_code == 201
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_missing_frontend_build_returns_clear_error(client, monkeypatch, tmp_path):
|
||||||
|
import app.main as main_module
|
||||||
|
|
||||||
|
monkeypatch.setattr(main_module, "FRONTEND_DIST", tmp_path)
|
||||||
|
response = await client.get("/some/route")
|
||||||
|
assert response.status_code == 503
|
||||||
|
assert "npm run build" in response.json()["detail"]
|
||||||
|
|||||||
Reference in New Issue
Block a user