objective_etl.get_sqlite_info: утечка SQLite-соединения/fd на error-path (close() не в finally) #1579

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

Severity: low · Категория: resource-leak · Файл: backend/app/services/objective_etl.py:468-477

Файл: backend/app/services/objective_etl.py:468-477.

Суть: c = sqlite3.connect(p) (469), три COUNT-запроса (470-474), затем c.close() (475) — всё в одном try, close ПОСЛЕ запросов и НЕ в finally. Если любой COUNT бросит sqlite3.Error (нет таблиц objective_lots/objective_corp_month/jk_objective_match или файл повреждён), управление прыгает в except sqlite3.Error (476-477), c.close() не вызывается -> соединение и файловый дескриптор остаются открытыми до GC.

Импакт: get_sqlite_info — admin-coverage endpoint (docstring 455-456), вызывается из UI для проверки свежести данных, потенциально часто. На частично-битом/неполном SQLite каждый вызов оставляет открытый fd -> накопление утечек хендлов на воркере. Не критично (GC закроет), но ресурс-лик на error-path. Severity low.

Фикс: with closing(sqlite3.connect(p)) as c: (contextlib.closing), либо перенести c.close() в finally. Предпочтительно closing(), т.к. with sqlite3.connect(...) управляет транзакцией, а не закрытием.

Почему баг: get_sqlite_info — admin-coverage endpoint, может вызываться часто из UI для проверки свежести данных. На частично-битом/неполном SQLite каждый вызов оставляет открытый дескриптор; накопление утечек файловых хендлов на воркере. Не критично (GC рано или поздно закроет), но это ресурс-лик именно на error-path.

Как чинить: Обернуть в try/finally с c.close() в finally, либо использовать with sqlite3.connect(p) as c: / contextlib.closing(sqlite3.connect(p)).


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

**Severity:** low · **Категория:** resource-leak · **Файл:** `backend/app/services/objective_etl.py:468-477` Файл: backend/app/services/objective_etl.py:468-477. Суть: `c = sqlite3.connect(p)` (469), три COUNT-запроса (470-474), затем `c.close()` (475) — всё в одном try, close ПОСЛЕ запросов и НЕ в finally. Если любой COUNT бросит sqlite3.Error (нет таблиц objective_lots/objective_corp_month/jk_objective_match или файл повреждён), управление прыгает в `except sqlite3.Error` (476-477), `c.close()` не вызывается -> соединение и файловый дескриптор остаются открытыми до GC. Импакт: get_sqlite_info — admin-coverage endpoint (docstring 455-456), вызывается из UI для проверки свежести данных, потенциально часто. На частично-битом/неполном SQLite каждый вызов оставляет открытый fd -> накопление утечек хендлов на воркере. Не критично (GC закроет), но ресурс-лик на error-path. Severity low. Фикс: `with closing(sqlite3.connect(p)) as c:` (contextlib.closing), либо перенести `c.close()` в `finally`. Предпочтительно closing(), т.к. `with sqlite3.connect(...)` управляет транзакцией, а не закрытием. **Почему баг:** get_sqlite_info — admin-coverage endpoint, может вызываться часто из UI для проверки свежести данных. На частично-битом/неполном SQLite каждый вызов оставляет открытый дескриптор; накопление утечек файловых хендлов на воркере. Не критично (GC рано или поздно закроет), но это ресурс-лик именно на error-path. **Как чинить:** Обернуть в `try/finally` с `c.close()` в finally, либо использовать `with sqlite3.connect(p) as c:` / `contextlib.closing(sqlite3.connect(p))`. --- <sub>deep-audit backend v2 (после PR #1543) · verify+harden, confidence 0.9 · unit B13</sub>
bot-backend added the
week ревью 1
label 2026-06-16 17:08:08 +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#1579
No description provided.