Files
Aislo/B03_FileInput/B03_FileInput_Router_Errors.py
T
eomsangdonandClaude Opus 5.5 f15104c607 fix(B03·공용): 지워진 프로젝트를 기억하면 빈 화면 대신 안내 · 서버 404(73-16)
- 라우터가 B03~B09 · 준비 화면 진입 전 현재 프로젝트를 한 번 확인 — 404 · 403 이면 기억을 비우고 「프로젝트가 없어졌습니다」 안내 + [대시보드로]
- workflow-state 는 지워진 프로젝트에 404(전: 200 빈 단계)
- 저장 경로 조회 실패는 ProjectNotFoundError(LookupError 하위) — 잡지 않은 자리도 앱 처리기가 404(전: 노선 API 등 500)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016PSXsvyDxjNmufteN5bqmt
2026-10-07 09:45:00 +09:00

38 lines
1.7 KiB
Python

"""B03 라우터 공통 오류 응답 — 조회 실패와 코드 버그를 갈라 준다.
`LookupError`를 통째로 404로 돌리면 `KeyError`·`IndexError` 같은 **코드 버그까지 404로
조용히 덮인다**. 실제로 업로드 finalize에서 `KeyError('role')`이 404 `{"message": "'role'"}`
로 나가 로그도 안 남고, 마지막 파일 업로드가 매번 실패로 보이던 사고가 있었다
(2026-08-08 E2E 점검). 조회 실패(레코드 없음)만 404로 두고 버그는 500 + 로그로 보낸다.
"""
import logging
from typing import Any
from fastapi import Request
from fastapi.responses import JSONResponse
def lookup_error_response(
exc: LookupError,
logger: logging.Logger,
*,
context: str,
fallback_message: str = "요청을 처리하지 못했습니다.",
**log_fields: Any,
) -> JSONResponse:
"""조회 실패면 404, 코드 버그(`KeyError`·`IndexError`)면 500 + 예외 로그."""
if isinstance(exc, (KeyError, IndexError)):
detail = " ".join(f"{key}=%s" for key in log_fields)
logger.exception(f"{context} 처리 중 내부 오류 {detail}".strip(), *log_fields.values())
return JSONResponse(
status_code=500,
content={"status": "error", "message": fallback_message},
)
return JSONResponse(status_code=404, content={"status": "error", "message": str(exc)})
async def project_not_found_response(_request: Request, exc: Exception) -> JSONResponse:
"""`ProjectNotFoundError` 앱 처리기(`main.py` 가 닮) — 잡지 않은 자리도 500 이 아닌 404."""
return JSONResponse(status_code=404, content={"status": "error", "message": str(exc)})