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
This commit is contained in:
@@ -109,6 +109,10 @@ async def get_project_input_readiness(
|
||||
return file_types, point_cloud_id, route_id
|
||||
|
||||
|
||||
class ProjectNotFoundError(LookupError):
|
||||
"""지워졌거나 없는 프로젝트 — 잡지 않은 자리는 앱 처리기가 404 로 답한다(500 아님)."""
|
||||
|
||||
|
||||
async def get_project_storage_relative_path(
|
||||
connection: aiomysql.Connection,
|
||||
project_id: UUID,
|
||||
@@ -126,7 +130,7 @@ async def get_project_storage_relative_path(
|
||||
row = await cursor.fetchone()
|
||||
|
||||
if not row or not row[0]:
|
||||
raise LookupError("프로젝트 또는 프로젝트 저장 경로를 찾을 수 없습니다.")
|
||||
raise ProjectNotFoundError("프로젝트 또는 프로젝트 저장 경로를 찾을 수 없습니다.")
|
||||
|
||||
normalized_path = PurePosixPath(str(row[0]).replace("\\", "/"))
|
||||
if normalized_path.is_absolute() or ".." in normalized_path.parts:
|
||||
|
||||
@@ -405,5 +405,14 @@ async def get_project_upload_overview(
|
||||
async def get_project_workflow_state(project_id: str):
|
||||
pool = get_db_pool()
|
||||
async with pool.acquire() as connection, connection.cursor(aiomysql.DictCursor) as cursor:
|
||||
# 지워진 프로젝트는 404 — 화면이 기억한 옛 id 를 알아채고 대시보드로 안내한다.
|
||||
await cursor.execute(
|
||||
"SELECT 1 FROM projects WHERE id = %s AND deleted_at IS NULL", (project_id,)
|
||||
)
|
||||
if not await cursor.fetchone():
|
||||
return JSONResponse(
|
||||
status_code=404,
|
||||
content={"status": "error", "message": "프로젝트를 찾을 수 없습니다."},
|
||||
)
|
||||
state = await get_workflow_state(cursor, project_id)
|
||||
return {"status": "success", "workflow_state": state}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from fastapi import Request
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
|
||||
@@ -29,3 +30,8 @@ def lookup_error_response(
|
||||
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)})
|
||||
|
||||
Reference in New Issue
Block a user