Working state before icon/utils fixes - Oct 22
This commit is contained in:
@@ -14,7 +14,7 @@ from typing import Union
|
||||
|
||||
from fastapi import Request, HTTPException
|
||||
from fastapi.exceptions import RequestValidationError
|
||||
from fastapi.responses import JSONResponse
|
||||
from fastapi.responses import JSONResponse, RedirectResponse
|
||||
|
||||
from .base import LetzShopException
|
||||
|
||||
@@ -26,7 +26,28 @@ def setup_exception_handlers(app):
|
||||
|
||||
@app.exception_handler(LetzShopException)
|
||||
async def custom_exception_handler(request: Request, exc: LetzShopException):
|
||||
"""Handle custom LetzVendor exceptions."""
|
||||
"""Handle custom exceptions."""
|
||||
|
||||
# Special handling for 401 on HTML page requests (redirect to login)
|
||||
if exc.status_code == 401 and _is_html_page_request(request):
|
||||
logger.info(
|
||||
f"401 on HTML page request - redirecting to login: {request.url.path}",
|
||||
extra={
|
||||
"path": request.url.path,
|
||||
"accept": request.headers.get("accept", ""),
|
||||
"method": request.method
|
||||
}
|
||||
)
|
||||
|
||||
# Redirect to appropriate login page
|
||||
if request.url.path.startswith("/admin"):
|
||||
logger.debug("Redirecting to /admin/login")
|
||||
return RedirectResponse(url="/admin/login", status_code=302)
|
||||
elif "/vendor/" in request.url.path:
|
||||
logger.debug("Redirecting to /vendor/login")
|
||||
return RedirectResponse(url="/vendor/login", status_code=302)
|
||||
# If neither, fall through to JSON response
|
||||
logger.debug("No specific redirect path matched, returning JSON")
|
||||
|
||||
logger.error(
|
||||
f"Custom exception in {request.method} {request.url}: "
|
||||
@@ -162,6 +183,51 @@ def setup_exception_handlers(app):
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def _is_html_page_request(request: Request) -> bool:
|
||||
"""
|
||||
Check if the request is for an HTML page (not an API endpoint).
|
||||
|
||||
More precise detection:
|
||||
- Must NOT have /api/ in path
|
||||
- Must be GET request
|
||||
- Must explicitly accept text/html
|
||||
- Must not already be on login page
|
||||
"""
|
||||
logger.debug(
|
||||
f"Checking if HTML page request: {request.url.path}",
|
||||
extra={
|
||||
"path": request.url.path,
|
||||
"method": request.method,
|
||||
"accept": request.headers.get("accept", "")
|
||||
}
|
||||
)
|
||||
|
||||
# Don't redirect API calls
|
||||
if "/api/" in request.url.path:
|
||||
logger.debug("Not HTML page: API endpoint")
|
||||
return False
|
||||
|
||||
# Don't redirect if already on login page
|
||||
if request.url.path.endswith("/login"):
|
||||
logger.debug("Not HTML page: Already on login page")
|
||||
return False
|
||||
|
||||
# Only redirect GET requests (page loads)
|
||||
if request.method != "GET":
|
||||
logger.debug(f"Not HTML page: Method is {request.method}, not GET")
|
||||
return False
|
||||
|
||||
# MUST explicitly accept HTML (strict check)
|
||||
accept_header = request.headers.get("accept", "")
|
||||
if "text/html" not in accept_header:
|
||||
logger.debug(f"Not HTML page: Accept header doesn't include text/html: {accept_header}")
|
||||
return False
|
||||
|
||||
logger.debug("IS HTML page request - will redirect on 401")
|
||||
return True
|
||||
|
||||
|
||||
# Utility functions for common exception scenarios
|
||||
def raise_not_found(resource_type: str, identifier: str) -> None:
|
||||
"""Convenience function to raise ResourceNotFoundException."""
|
||||
|
||||
Reference in New Issue
Block a user