Исправление ошибок, добавление ИИ-ассистента

This commit is contained in:
2026-02-16 14:43:14 +03:00
parent 5b7ea9276b
commit 213d2bcb5a
18 changed files with 1672 additions and 426 deletions
+10
View File
@@ -0,0 +1,10 @@
"""Пакет middleware"""
from .catch_exception import catch_exception_middleware
from .log_request import log_request_middleware
from .not_found_handler import not_found_handler
__all__ = [
"catch_exception_middleware",
"log_request_middleware",
"not_found_handler",
]
@@ -0,0 +1,27 @@
import sys
from fastapi import Request, Response, status
from starlette.middleware.base import BaseHTTPMiddleware
from fastapi.responses import JSONResponse
from library_service.settings import get_logger
async def catch_exception_middleware(request: Request, call_next):
"""Middleware для подробного json-описания Internal error"""
try:
return await call_next(request)
except Exception as exc:
exc_type, exc_value, exc_tb = sys.exc_info()
logger = get_logger()
logger.exception(exc)
return JSONResponse(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content={
"message": str(exc),
"type": exc_type.__name__ if exc_type else "Unknown",
"path": str(request.url),
"method": request.method,
},
)
@@ -0,0 +1,72 @@
from datetime import datetime
from time import perf_counter
from uuid import uuid4
from fastapi import Request, Response, status
from library_service.settings import get_logger
SKIP_LOGGING_PATHS = frozenset({"/favicon.ico", "/favicon.svg"})
async def log_request_middleware(request: Request, call_next):
"""Middleware для логирования HTTP-запросов"""
path = request.url.path
if path.startswith("/static") or path in SKIP_LOGGING_PATHS:
return await call_next(request)
logger = get_logger()
request_id = uuid4().hex[:8]
timestamp = datetime.now().isoformat()
method = request.method
url = str(request.url)
user_agent = request.headers.get("user-agent", "Unknown")
client_ip = request.client.host if request.client else None
start_time = perf_counter()
try:
logger.debug(
f"[{request_id}] Starting: {method} {url}",
extra={"request_id": request_id, "user_agent": user_agent},
)
response: Response = await call_next(request)
process_time = perf_counter() - start_time
logger.info(
f"[{request_id}] {method} {url} - {response.status_code} - {process_time:.4f}s",
extra={
"request_id": request_id,
"timestamp": timestamp,
"method": method,
"url": url,
"status": response.status_code,
"process_time": process_time,
"client_ip": client_ip,
"user_agent": user_agent,
},
)
return response
except Exception as e:
process_time = perf_counter() - start_time
logger.error(
f"[{request_id}] {method} {url} - Error: {e} - {process_time:.4f}s",
extra={
"request_id": request_id,
"timestamp": timestamp,
"method": method,
"url": url,
"error": str(e),
"process_time": process_time,
"client_ip": client_ip,
"user_agent": user_agent,
},
exc_info=True,
)
return Response(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content="Internal Server Error",
)
@@ -0,0 +1,24 @@
from fastapi import Request, Response, status, HTTPException
from fastapi.responses import JSONResponse
from library_service.settings import get_app
from library_service.routers.misc import unknown
async def not_found_handler(request: Request, exc: HTTPException):
"""Middleware для обработки 404 ошибки"""
if exc.detail == "Not Found":
path = request.url.path
if path.startswith("/api/"):
return JSONResponse(
status_code=status.HTTP_404_NOT_FOUND,
content={"detail": "API endpoint not found", "path": path},
)
app = get_app()
return await unknown(request, app)
return JSONResponse(
status_code=exc.status_code,
content={"detail": exc.detail},
)