еще правки

This commit is contained in:
Raykov-MS 2026-06-16 15:22:39 +03:00
parent 2f5cb21dc0
commit 5210f1d6f7
2 changed files with 38 additions and 0 deletions

View File

@ -1,4 +1,5 @@
from fastapi import FastAPI, HTTPException, status
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
from sqlalchemy.exc import IntegrityError, OperationalError, SQLAlchemyError, DBAPIError
@ -94,7 +95,28 @@ def map_http_exception(exc: HTTPException) -> tuple[int, int, str, str]:
return status_code, status_code, message, ""
def map_request_validation_error(exc: RequestValidationError) -> tuple[int, int, str, str]:
status_code = status.HTTP_422_UNPROCESSABLE_ENTITY
errors = exc.errors()
if not errors:
return status_code, status_code, "Validation error", ""
first_error = errors[0]
message = str(first_error.get("msg") or "Validation error")
loc = first_error.get("loc") or ()
field = ".".join(str(part) for part in loc if part not in ("body", "query", "path", "header", "cookie"))
return status_code, status_code, message, field
def register_exception_handlers(app: FastAPI) -> None:
@app.exception_handler(RequestValidationError)
async def request_validation_exception_handler(request, exc: RequestValidationError):
status_code, code, message, field = map_request_validation_error(exc)
return JSONResponse(
status_code=status_code,
content=_error_payload(code, message, field=field),
)
@app.exception_handler(HTTPException)
async def http_exception_handler(request, exc: HTTPException):
status_code, code, message, field = map_http_exception(exc)

View File

@ -29,6 +29,10 @@ def _make_app() -> FastAPI:
exc.orig = Exception("budget_form #99 не существует")
raise exc
@app.get("/form/{form_id}")
async def form_by_id(form_id: int):
return {"form_id": form_id}
return app
@ -66,3 +70,15 @@ def test_sqlalchemy_exception_returns_structured_payload():
"field": "",
"message": "budget_form #99 не существует",
}
def test_request_validation_422_returns_structured_payload():
client = TestClient(_make_app())
response = client.get("/form/not-int")
assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
assert response.json() == {
"code": status.HTTP_422_UNPROCESSABLE_ENTITY,
"field": "form_id",
"message": "Input should be a valid integer, unable to parse string as an integer",
}