From 472acd580441ecc7750048017ccda68838587702 Mon Sep 17 00:00:00 2001 From: Viktor Barzin Date: Sat, 9 May 2026 23:00:58 +0000 Subject: [PATCH] app: catch starlette.HTTPException in SPA fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit StaticFiles is a Starlette primitive — its 404 raises starlette.exceptions.HTTPException, NOT fastapi.HTTPException (which subclasses Starlette's). My initial except clause caught the subclass and let the base class propagate, so /scenarios still 404'd. Switch to except StarletteHTTPException so both the parent and any FastAPI subclass are caught. Verified end-to-end via chrome-service in the next deploy. Co-Authored-By: Claude Opus 4.7 --- fire_planner/app.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fire_planner/app.py b/fire_planner/app.py index 3253f2a..6e352f9 100644 --- a/fire_planner/app.py +++ b/fire_planner/app.py @@ -33,11 +33,11 @@ from pathlib import Path from typing import Any from fastapi import Depends, FastAPI, status -from fastapi.exceptions import HTTPException from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import FileResponse from fastapi.staticfiles import StaticFiles from prometheus_fastapi_instrumentator import Instrumentator +from starlette.exceptions import HTTPException as StarletteHTTPException from starlette.types import Scope from fire_planner.api.auth import require_bearer @@ -159,7 +159,7 @@ class _SPAStaticFiles(StaticFiles): async def get_response(self, path: str, scope: Scope): # type: ignore[no-untyped-def] try: return await super().get_response(path, scope) - except HTTPException as exc: + except StarletteHTTPException as exc: if exc.status_code == 404: index = Path(self.directory) / "index.html" # type: ignore[arg-type] if index.is_file():