FastAPI에서 Pydantic 모델 검증 실패 시 커스텀 에러 응답 처리
문제 상황
FastAPI 프로젝트에서 Pydantic 모델의 검증 실패 시 반환되는 기본 에러 포맷이 프론트엔드 팀에서 파싱하기 어렵다는 피드백을 받았다. 특히 중첩된 모델 검증 실패 시 에러 위치를 특정하기 힘들다는 문제가 있었다.
기본 에러 응답
# 422 Unprocessable Entity
{
"detail": [
{
"loc": ["body", "email"],
"msg": "field required",
"type": "value_error.missing"
}
]
}
해결 방법
RequestValidationError에 대한 커스텀 exception handler를 등록했다.
from fastapi import FastAPI, Request, status
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
app = FastAPI()
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
errors = {}
for error in exc.errors():
field = ".".join(str(loc) for loc in error["loc"][1:])
errors[field] = {
"message": error["msg"],
"type": error["type"]
}
return JSONResponse(
status_code=status.HTTP_400_BAD_REQUEST,
content={
"success": False,
"errors": errors
}
)
개선된 응답
{
"success": false,
"errors": {
"email": {
"message": "field required",
"type": "value_error.missing"
}
}
}
필드명을 키로 사용해 프론트엔드에서 특정 input에 에러 메시지를 바로 매핑할 수 있게 되었다. 상태 코드도 422 대신 400으로 통일해 다른 API와 일관성을 맞췄다.
다음 스프린트에서는 i18n을 적용해 다국어 에러 메시지도 지원할 예정이다.