ddu_price_indicator: missing MV даёт ProgrammingError, а ловится только OperationalError — диагностический except мёртв для своего же кейса #1582

Closed
opened 2026-06-16 17:08:12 +00:00 by bot-backend · 0 comments
Collaborator

Severity: low · Категория: wrong_exception_type · Файл: backend/app/services/analytics/ddu_price_indicator.py:160-190

Файл /Users/anton/Птица/gendesign/backend/app/services/analytics/ddu_price_indicator.py:187 — SELECT к mv_ddu_price_indicator обёрнут в except OperationalError: с комментарием (line 188) 'Most likely the MV does not exist yet (migration 152 not applied)'. В PostgreSQL отсутствие отношения — SQLSTATE 42P01 (UndefinedTable), который psycopg v3/SQLAlchemy маппит в sqlalchemy.exc.ProgrammingError, НЕ OperationalError (ProgrammingError даже не импортирован — line 31 импортирует только OperationalError). Поэтому когда миграция 152 не применена, целевой диагностический лог (line 189, logger.exception '... mv_ddu_price_indicator missing?') НЕ срабатывает именно для того кейса, под который написан.

Импакт ограничен: блок всё равно делает raise (line 190), так что поведение наружу идентично (тот же 500) — теряется только намеренное диагностическое логирование. Поэтому severity low. По всему остальному кодбейзу этот кейс ловится обоими исключениями: backend/app/services/site_finder/okn_lookup.py:81, krt_lookup.py:134/179, reservation_lookup.py:49, planning_lookup.py:49, pat_lookup.py:49, functional_zone_lookup.py:50, granddoc_lookup.py:92 — все except (OperationalError, ProgrammingError).

Фикс: import ProgrammingError из sqlalchemy.exc и заменить на except (OperationalError, ProgrammingError): — в соответствии с принятым в репозитории паттерном.

Почему баг: When migration 152 has not been applied, the SELECT raises ProgrammingError, which skips the except OperationalError block entirely. The targeted 'mv_ddu_price_indicator missing?' diagnostic log (line 189) never fires for the very condition it was written for; the exception propagates as a generic 500 with no helpful log. Impact is limited because the handler re-raises anyway, so behavior is the same crash either way — only the intended diagnostic logging is lost. The refresh-fallback string-match path (lines 265-272) mirrors the accepted repo pattern in quarter_price_index_refresh.py, so it is not flagged.

Как чинить: Import ProgrammingError from sqlalchemy.exc and change line 187 to except (OperationalError, ProgrammingError):, matching the established convention in the site_finder lookup modules.


deep-audit backend v2 (после PR #1543) · verify+harden, confidence 0.82 · unit B15

**Severity:** low · **Категория:** wrong_exception_type · **Файл:** `backend/app/services/analytics/ddu_price_indicator.py:160-190` Файл /Users/anton/Птица/gendesign/backend/app/services/analytics/ddu_price_indicator.py:187 — SELECT к mv_ddu_price_indicator обёрнут в except OperationalError: с комментарием (line 188) 'Most likely the MV does not exist yet (migration 152 not applied)'. В PostgreSQL отсутствие отношения — SQLSTATE 42P01 (UndefinedTable), который psycopg v3/SQLAlchemy маппит в sqlalchemy.exc.ProgrammingError, НЕ OperationalError (ProgrammingError даже не импортирован — line 31 импортирует только OperationalError). Поэтому когда миграция 152 не применена, целевой диагностический лог (line 189, logger.exception '... mv_ddu_price_indicator missing?') НЕ срабатывает именно для того кейса, под который написан. Импакт ограничен: блок всё равно делает raise (line 190), так что поведение наружу идентично (тот же 500) — теряется только намеренное диагностическое логирование. Поэтому severity low. По всему остальному кодбейзу этот кейс ловится обоими исключениями: backend/app/services/site_finder/okn_lookup.py:81, krt_lookup.py:134/179, reservation_lookup.py:49, planning_lookup.py:49, pat_lookup.py:49, functional_zone_lookup.py:50, granddoc_lookup.py:92 — все except (OperationalError, ProgrammingError). Фикс: import ProgrammingError из sqlalchemy.exc и заменить на except (OperationalError, ProgrammingError): — в соответствии с принятым в репозитории паттерном. **Почему баг:** When migration 152 has not been applied, the SELECT raises `ProgrammingError`, which skips the `except OperationalError` block entirely. The targeted 'mv_ddu_price_indicator missing?' diagnostic log (line 189) never fires for the very condition it was written for; the exception propagates as a generic 500 with no helpful log. Impact is limited because the handler re-raises anyway, so behavior is the same crash either way — only the intended diagnostic logging is lost. The refresh-fallback string-match path (lines 265-272) mirrors the accepted repo pattern in quarter_price_index_refresh.py, so it is not flagged. **Как чинить:** Import `ProgrammingError` from `sqlalchemy.exc` and change line 187 to `except (OperationalError, ProgrammingError):`, matching the established convention in the site_finder lookup modules. --- <sub>deep-audit backend v2 (после PR #1543) · verify+harden, confidence 0.82 · unit B15</sub>
bot-backend added the
week ревью 1
label 2026-06-16 17:08:12 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#1582
No description provided.