From ab6a6b74e9b9a5f61e5d4f01f8ede8a4700cf2cb Mon Sep 17 00:00:00 2001 From: Mina Choi Date: Mon, 14 Sep 2026 17:07:23 +0900 Subject: [PATCH] =?UTF-8?q?[fix]=20solution/backend:=20=EB=B0=9C=ED=96=89?= =?UTF-8?q?=20=EB=AF=B8=EB=A6=AC=EB=B3=B4=EA=B8=B0=EA=B0=80=20=EC=A7=80?= =?UTF-8?q?=EC=97=AD=20=EC=A0=95=EB=B3=B4=20=ED=95=9C=20=EC=B9=B8=20?= =?UTF-8?q?=EB=95=8C=EB=AC=B8=EC=97=90=20=ED=86=B5=EC=A7=B8=EB=A1=9C=20500?= =?UTF-8?q?=20=EB=82=98=EB=8D=98=20=EA=B2=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _select() 는 조회 실패를 빈 목록으로 삼키도록 짜여 있었는데, DB 계층 기본값이 raise_error=True 라 그 처리가 실행될 기회조차 없이 예외가 먼저 터졌다. 실측: place_songs 테이블이 없던 동안 미리보기가 통째로 HTTP 500 이었다 — 노래 한 칸이 빠진 화면 대신 아무것도 못 보는 화면이 나갔다. - snapshot.py: _local_contents · _site_places · _select 의 DB 조회에 raise_error=False 를 명시 — 실패는 그 칸만 비우고 나머지는 그대로 그린다. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01XYUb8ZfNiDd15tZRYrusCX --- solution/backend/services/snapshot.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/solution/backend/services/snapshot.py b/solution/backend/services/snapshot.py index 8eaade2..17a8d15 100644 --- a/solution/backend/services/snapshot.py +++ b/solution/backend/services/snapshot.py @@ -252,7 +252,7 @@ async def _local_contents(place) -> dict: .order_by(area_contents.content_type.asc(), area_contents.collected_at.desc()) ) err, rows = await DB_SESSION_MNG.execute_lambda( - area_contents.DBType(), DBWRType.DB_READ.value, lambda s: DB_SESSION_MNG.execute(s, query) + area_contents.DBType(), DBWRType.DB_READ.value, lambda s: DB_SESSION_MNG.execute(s, query, raise_error=False) ) if err != ErrorType.SUCCESS: # ★ 지역 정보가 없다고 발행을 막지 않는다 — 사업장의 사실이 아니라 곁들이는 정보다. @@ -277,7 +277,7 @@ async def _local_contents(place) -> dict: ) err, rows = await DB_SESSION_MNG.execute_lambda( area_contents.DBType(), DBWRType.DB_READ.value, - lambda s: DB_SESSION_MNG.execute(s, shared_q), + lambda s: DB_SESSION_MNG.execute(s, shared_q, raise_error=False), ) if err != ErrorType.SUCCESS: LOG.w(f"[snapshot] 주변 정보 조회 실패 place={place_id}: {err.name}") @@ -353,7 +353,7 @@ async def _site_places(place_id) -> dict: .limit(1) ) err, rows = await DB_SESSION_MNG.execute_lambda( - site_sections.DBType(), DBWRType.DB_READ.value, lambda s: DB_SESSION_MNG.execute(s, q) + site_sections.DBType(), DBWRType.DB_READ.value, lambda s: DB_SESSION_MNG.execute(s, q, raise_error=False) ) if err != ErrorType.SUCCESS or not rows: return {} @@ -405,9 +405,16 @@ def _iso(value) -> str | None: async def _select(query) -> list: + """조회 실패는 **빈 목록**이다 — 미리보기·발행이 조각 하나 때문에 통째로 죽지 않게. + + ★ raise_error=False 가 핵심이다 (2026-09-14). 이 함수는 원래 실패를 [] 로 삼키도록 + 썼는데, DB 계층이 기본값 raise_error=True 로 **예외를 던져** 그 처리가 실행될 기회조차 + 없었다. 실측: place_songs 테이블이 없던 동안 미리보기가 통째로 HTTP 500 이었다 — + 노래 한 칸이 빠진 화면 대신 아무것도 못 보는 화면이 나갔다. + """ err, rows = await DB_SESSION_MNG.execute_lambda( place_facts.DBType(), DBWRType.DB_READ.value, - lambda s: DB_SESSION_MNG.execute(s, query), + lambda s: DB_SESSION_MNG.execute(s, query, raise_error=False), ) return list(rows) if err == ErrorType.SUCCESS else []