[objective_etl] import_anton_objective: FileNotFoundError возвращает dict без raise — Celery-таск SUCCESS при проваленном ETL #1623

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

Severity: low · Категория: logic/terminal-state · Файл: backend/app/workers/tasks/objective_etl.py:149-158

Файл: backend/app/workers/tasks/objective_etl.py:149-158. В ветке except FileNotFoundError задача вызывает _finish_run(status='failed') и затем return {'run_id': run_id, 'error': 'sqlite_not_found', ...} БЕЗ re-raise. Для сравнения, общий except Exception (строки 160-167) корректно делает raise. Таск объявлен с max_retries=0 (строка 90).

Импакт: возврат dict из Celery-таска = терминальное состояние SUCCESS в result backend, хотя ETL фактически провалился (нет SQLite-файла). Рассинхрон: строка objective_scrape_runs помечена 'failed' (через _finish_run), а Celery-таск — 'succeeded'. Мониторинг/алертинг, опирающийся на статус Celery-таска (а не на таблицу), не увидит провал. Импакт ограничен: это ручной legacy/bootstrap ETL (docstring строки 1-19: триггерится только вручную через POST /admin/scrape/objective, beat-расписания нет), частота низкая, в БД статус корректен. Severity low.

Фикс: после _finish_run(status='failed') в FileNotFoundError-ветке либо raise, либо вернуть результат и заодно пометить таск проваленным (например через self.update_state(state='FAILURE')), чтобы Celery-статус соответствовал реальному провалу.

Почему баг: Возврат dict из Celery-таска означает терминальное состояние SUCCESS в Celery result backend, хотя ETL фактически провалился (файла SQLite нет). Получается рассинхрон: строка objective_scrape_runs помечена 'failed', а сам Celery-таск — 'succeeded'. Любой мониторинг/алертинг по статусу Celery-таска (а не по таблице) не увидит провал. Импакт ограничен: это ручной legacy/bootstrap-ETL без beat-расписания, частота низкая, в БД статус корректный. Поэтому low.

Как чинить: После _finish_run(status='failed') в ветке FileNotFoundError либо re-raise (как в общей ветке), либо явно вернуть сигнал-провал и завести задачу как FAILURE через self.update_state/исключение. Минимум — задокументировать что Celery-статус по этой задаче не показателен.


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

**Severity:** low · **Категория:** logic/terminal-state · **Файл:** `backend/app/workers/tasks/objective_etl.py:149-158` Файл: backend/app/workers/tasks/objective_etl.py:149-158. В ветке `except FileNotFoundError` задача вызывает _finish_run(status='failed') и затем `return {'run_id': run_id, 'error': 'sqlite_not_found', ...}` БЕЗ re-raise. Для сравнения, общий `except Exception` (строки 160-167) корректно делает raise. Таск объявлен с max_retries=0 (строка 90). Импакт: возврат dict из Celery-таска = терминальное состояние SUCCESS в result backend, хотя ETL фактически провалился (нет SQLite-файла). Рассинхрон: строка objective_scrape_runs помечена 'failed' (через _finish_run), а Celery-таск — 'succeeded'. Мониторинг/алертинг, опирающийся на статус Celery-таска (а не на таблицу), не увидит провал. Импакт ограничен: это ручной legacy/bootstrap ETL (docstring строки 1-19: триггерится только вручную через POST /admin/scrape/objective, beat-расписания нет), частота низкая, в БД статус корректен. Severity low. Фикс: после _finish_run(status='failed') в FileNotFoundError-ветке либо `raise`, либо вернуть результат и заодно пометить таск проваленным (например через self.update_state(state='FAILURE')), чтобы Celery-статус соответствовал реальному провалу. **Почему баг:** Возврат dict из Celery-таска означает терминальное состояние SUCCESS в Celery result backend, хотя ETL фактически провалился (файла SQLite нет). Получается рассинхрон: строка objective_scrape_runs помечена 'failed', а сам Celery-таск — 'succeeded'. Любой мониторинг/алертинг по статусу Celery-таска (а не по таблице) не увидит провал. Импакт ограничен: это ручной legacy/bootstrap-ETL без beat-расписания, частота низкая, в БД статус корректный. Поэтому low. **Как чинить:** После _finish_run(status='failed') в ветке FileNotFoundError либо re-raise (как в общей ветке), либо явно вернуть сигнал-провал и завести задачу как FAILURE через self.update_state/исключение. Минимум — задокументировать что Celery-статус по этой задаче не показателен. --- <sub>deep-audit backend v2 (после PR #1543) · verify+harden, confidence 0.92 · unit B45</sub>
bot-backend added the
week ревью 1
label 2026-06-16 17:21:54 +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#1623
No description provided.