한양과학기술고등학교

에듀테크 프로젝트 대시보드

에러 처리

HTTPException exception_handler detail headers

예상된 실패는 HTTPException 으로, 공통 처리가 필요하면 예외 핸들러로.

1. HTTPException

from fastapi import HTTPException

@app.get("/items/{id}")
def read(id: int):
    item = db.get(id)
    if item is None:
        raise HTTPException(
            status_code=404,
            detail="아이템을 찾을 수 없습니다",
            headers={"X-Error": "not-found"},
        )
    return item

raise 로 던지면 나머지 코드가 실행되지 않고 즉시 응답이 반환됩니다.

2. 커스텀 예외 + 핸들러

from fastapi import Request
from fastapi.responses import JSONResponse

class OutOfStock(Exception):
    def __init__(self, sku: str):
        self.sku = sku

@app.exception_handler(OutOfStock)
async def handle_out_of_stock(request: Request, exc: OutOfStock):
    return JSONResponse(
        status_code=409,
        content={"detail": f"{exc.sku} 재고 없음"},
    )

@app.post("/buy/{sku}")
def buy(sku: str):
    if not in_stock(sku):
        raise OutOfStock(sku)

3. 검증 에러 형식 바꾸기

from fastapi.exceptions import RequestValidationError

@app.exception_handler(RequestValidationError)
async def validation_handler(request: Request, exc: RequestValidationError):
    return JSONResponse(
        status_code=422,
        content={"ok": False, "errors": exc.errors()},
    )

4. 전역 예외 (500)

@app.exception_handler(Exception)
async def unhandled(request: Request, exc: Exception):
    logger.exception("unhandled", exc_info=exc)
    return JSONResponse(status_code=500, content={"detail": "서버 오류"})
주의
  • 전역 Exception 핸들러를 두면 디버그 모드 traceback 페이지가 가려짐 — 로깅을 반드시 남길 것
"API 스키마는 코드가 곧 문서다 (/docs)"