- app.py: create_app(settings), SMB-сессия только при SCAN_HOTFOLDER_MODE=smb, без SPA/CORS/РАИСА/nkeys; /healthcheck отдаёт uptime и version - config.py: ENV_FILE, get_settings() с lru_cache, параметры горячих папок/NATS, блок OPENBAO__SMB необязателен, валидация режимов local/smb; убраны DBSettings и OPENBAO.DATABASE - exception_handlers.py: убрана зависимость от sqlalchemy - requirements.txt: убраны asyncpg, SQLAlchemy, alembic, argon2-cffi(+bindings), raisa_*, greenlet, Mako - api/.env.example: минимальный local-режим против compose; unit-тесты config/app Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
29 lines
1.2 KiB
Python
29 lines
1.2 KiB
Python
from fastapi import FastAPI, HTTPException, Request, status
|
||
from fastapi.exceptions import RequestValidationError
|
||
from fastapi.responses import JSONResponse
|
||
|
||
|
||
def register_exception_handlers(app: FastAPI) -> None:
|
||
@app.exception_handler(RequestValidationError)
|
||
async def request_validation_exception_handler(_: Request, exc: RequestValidationError):
|
||
return JSONResponse(
|
||
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||
content={"detail": exc.errors()},
|
||
)
|
||
|
||
@app.exception_handler(HTTPException)
|
||
async def http_exception_handler(_: Request, exc: HTTPException):
|
||
# Не ломаем существующие ответы endpoint-ов и прокидываем исходный detail.
|
||
return JSONResponse(
|
||
status_code=exc.status_code,
|
||
content={"detail": exc.detail},
|
||
headers=exc.headers,
|
||
)
|
||
|
||
@app.exception_handler(Exception)
|
||
async def unhandled_exception_handler(_: Request, exc: Exception):
|
||
return JSONResponse(
|
||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||
content={"detail": "внутренняя ошибка сервера"},
|
||
)
|