Keep API not-found and 401 responses usable behind Ingress and in the Web UI.

Return native JSON with the missing id in the message, clear stale sessions on
401, and document ingress-nginx annotations so branded HTML 404/405 pages do
not rewrite simulator bodies.
This commit is contained in:
2026-07-22 06:52:35 +03:00
parent 131e2e63d2
commit e8b08526d1
13 changed files with 260 additions and 62 deletions
+24
View File
@@ -6,6 +6,9 @@ import asyncio
from typing import cast
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from starlette.exceptions import HTTPException as StarletteHTTPException
from starlette.requests import Request as StarletteRequest
from app.api.errors import ApiError, api_error_handler, unhandled_exception_handler
from app.api.middleware import HeadAsGetMiddleware, RequestContextMiddleware
@@ -30,6 +33,26 @@ from app.vsphere.soap.router import router as vsphere_soap_router
from app.web.routes import router as web_router
async def _json_http_exception_handler(
_request: StarletteRequest, exc: StarletteHTTPException
) -> JSONResponse:
"""Always return JSON for HTTP errors — never HTML error pages from the app."""
detail = exc.detail
if isinstance(detail, dict):
# VsphereError and similar already carry the product envelope in detail.
content: dict | list = {"detail": detail}
elif isinstance(detail, list):
content = {"detail": detail}
else:
content = {"detail": detail}
return JSONResponse(
status_code=exc.status_code,
content=content,
media_type="application/json",
)
def create_app(
settings: Settings | None = None,
database_factory: DatabaseFactory = default_database_factory,
@@ -110,6 +133,7 @@ def create_app(
app.add_middleware(VsphereVersionGateMiddleware)
app.add_exception_handler(Exception, unhandled_exception_handler)
app.add_exception_handler(ApiError, api_error_handler)
app.add_exception_handler(StarletteHTTPException, _json_http_exception_handler)
# Native vSphere surface (survives contract hot-swap).
from app.vsphere.soap.pbm import router as vsphere_pbm_router