update to python fastpi

This commit is contained in:
Iliyan Angelov
2025-11-16 15:59:05 +02:00
parent 93d4c1df80
commit 98ccd5b6ff
4464 changed files with 773233 additions and 13740 deletions

View File

@@ -0,0 +1,127 @@
from fastapi import Request, status, HTTPException
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from sqlalchemy.exc import IntegrityError
from jose.exceptions import JWTError
import os
import traceback
async def validation_exception_handler(request: Request, exc: RequestValidationError):
"""
Handle validation errors
"""
errors = []
for error in exc.errors():
field = ".".join(str(loc) for loc in error["loc"] if loc != "body")
errors.append({
"field": field,
"message": error["msg"]
})
# Get the first error message for the main message
first_error = errors[0]["message"] if errors else "Validation error"
return JSONResponse(
status_code=status.HTTP_400_BAD_REQUEST,
content={
"status": "error",
"message": first_error,
"errors": errors
}
)
async def integrity_error_handler(request: Request, exc: IntegrityError):
"""
Handle database integrity errors (unique constraints, etc.)
"""
error_msg = str(exc.orig) if hasattr(exc, 'orig') else str(exc)
# Check for duplicate entry
if "Duplicate entry" in error_msg or "UNIQUE constraint" in error_msg:
return JSONResponse(
status_code=status.HTTP_400_BAD_REQUEST,
content={
"status": "error",
"message": "Duplicate entry",
"errors": [{"message": "This record already exists"}]
}
)
return JSONResponse(
status_code=status.HTTP_400_BAD_REQUEST,
content={
"status": "error",
"message": "Database integrity error"
}
)
async def jwt_error_handler(request: Request, exc: JWTError):
"""
Handle JWT errors
"""
return JSONResponse(
status_code=status.HTTP_401_UNAUTHORIZED,
content={
"status": "error",
"message": "Invalid token"
}
)
async def http_exception_handler(request: Request, exc: HTTPException):
"""
Handle HTTPException errors
"""
# If detail is already a dict with status/message, return it directly
if isinstance(exc.detail, dict):
return JSONResponse(
status_code=exc.status_code,
content=exc.detail
)
# Otherwise format as standard error response
return JSONResponse(
status_code=exc.status_code,
content={
"status": "error",
"message": str(exc.detail) if exc.detail else "An error occurred"
}
)
async def general_exception_handler(request: Request, exc: Exception):
"""
Handle all other exceptions
"""
# Log error
print(f"Error: {exc}")
if os.getenv("NODE_ENV") == "development":
traceback.print_exc()
# Handle HTTPException with dict detail
if isinstance(exc, Exception) and hasattr(exc, "status_code"):
status_code = exc.status_code
if hasattr(exc, "detail"):
detail = exc.detail
if isinstance(detail, dict):
# If detail is already a dict with status/message, return it directly
return JSONResponse(status_code=status_code, content=detail)
message = str(detail) if detail else "An error occurred"
else:
message = str(exc) if str(exc) else "Internal server error"
else:
status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
message = str(exc) if str(exc) else "Internal server error"
return JSONResponse(
status_code=status_code,
content={
"status": "error",
"message": message,
**({"stack": traceback.format_exc()} if os.getenv("NODE_ENV") == "development" else {})
}
)