Два способа возвращать ошибки из FastAPI-эндпоинта. Какой правильный?
middle
correct_vs_wrong
#347
Вариант 1
@app.post("/orders")
async def create_order(body: CreateOrderIn):
try:
order = await order_service.create(body)
except StockEmptyError as e:
return {"error": str(e), "code": "STOCK_EMPTY"}, 409 # ❌ tuple — это не valid FastAPI return
except Exception as e:
return {"error": "internal"}, 500
return order
Вариант 2
from fastapi import HTTPException, status
class StockEmptyError(Exception):
pass
# Один централизованный handler
@app.exception_handler(StockEmptyError)
async def stock_empty_handler(request: Request, exc: StockEmptyError):
return JSONResponse(
status_code=status.HTTP_409_CONFLICT,
content={"detail": str(exc), "code": "STOCK_EMPTY"},
)
@app.post(
"/orders",
response_model=OrderOut,
status_code=201,
responses={409: {"description": "Stock empty"}},
)
async def create_order(body: CreateOrderIn):
# Бросаем — пусть handler разрулит. Эндпоинт чистый.
order = await order_service.create(body)
return order
# При генерации OpenAPI — будет 409 в схеме, фронт это увидит.
Чтобы решить вопрос и сохранить попытку — войди.