еще правки
This commit is contained in:
parent
2f5cb21dc0
commit
5210f1d6f7
@ -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)
|
||||
|
||||
@ -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",
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user