Add a handler to make the structure of validation errors consistent.

main
KKlochko 1 month ago
parent 763773ee51
commit 59caa6a0ab
Signed by: KKlochko
GPG Key ID: 572ECCD219BBA91B

@ -1,4 +1,5 @@
from fastapi import FastAPI, HTTPException, status
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
from starlette.requests import Request
from typing import List, Optional, Union, Dict, Any, Tuple
@ -71,6 +72,36 @@ async def http_exception_handler(request: Request, exc: HTTPException):
content=response_body
)
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
"""
Handles Pydantic validation errors (normally 422) and returns them as 400 Bad Request
with a consistent error structure.
Return first validation error.
"""
# Extract validation error details
errors = exc.errors()
# Get first error:
location = " -> ".join(str(l) for l in errors[0]["loc"])
error_message = f"{location}: {errors[0]['msg']}"
response_body = {
"error": {
"code": "INVALID_INPUT",
"message": error_message,
"details": {}
}
}
return JSONResponse(
# Changed from 422 to 400
status_code=400,
content=response_body
)
# ==================== Endpoints ====================
@app.get("/health")
async def health_check():

@ -89,7 +89,7 @@ class TestGeneralEndpoint:
"entities": []
}
response = api_client.post(f"{BASE_URL}/general", json=payload)
assert response.status_code == 422 # Pydantic validation error
assert response.status_code == 400
def test_error_empty_texts_list(self, api_client):
"""Test error with an empty texts list"""
@ -109,7 +109,7 @@ class TestGeneralEndpoint:
"threshold": threshold
}
response = api_client.post(f"{BASE_URL}/general", json=payload)
assert response.status_code == 422
assert response.status_code == 400
@pytest.mark.parametrize("threshold", [0.0, 0.5, 1.0])
def test_valid_threshold_range(self, api_client, threshold):

@ -73,7 +73,7 @@ class TestRelationExtractionEndpoint:
"relations": []
}
response = api_client.post(f"{BASE_URL}/relation-extraction", json=payload)
assert response.status_code == 422
assert response.status_code == 400
def test_error_both_text_and_texts(self, api_client):
"""Test error when both text and texts are present"""

Loading…
Cancel
Save