tasks: заведены шесть задач из урожая ревью и переименования образца конфига
- пять из урожая change 2026-08-11-fix-http-handler-tests, тег review-2026-08-11; утечка имени файла в журнал поставлена первой строкой очереди - опечатка transcibe дописана в json-api-for-spa: текст ошибки — часть необратимого контракта, и в одиночку он не правится
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
# 🐞 Убирать записанный файл, когда приём отказал на середине
|
||||
|
||||
- **Тип:** fix
|
||||
- **Категория:** Очередь
|
||||
- **Зачем:** Отказ чтения метаданных и отказ записи на диск оставляют файл в каталоге хранения без задачи и без учёта: сопоставить его не с чем, удалять приходится руками.
|
||||
- **Теги:** review-2026-08-11
|
||||
|
||||
Приём пишет файл на диск, потом спрашивает у источника метаданных длительность,
|
||||
потом заводит запись в учёте и задачу. Уборка при отказе есть **только на
|
||||
последнем шаге**: отказ `fileRepo.Create` зовёт `os.Remove`, а отказы записи на
|
||||
диск и чтения метаданных возвращают ошибку, оставляя файл лежать.
|
||||
|
||||
Сопоставить такой файл не с чем: записи в `files` под него нет, задачи нет,
|
||||
имя — случайный идентификатор. На сервере это `data/files`, где лежат голосовые
|
||||
сообщения живых людей, а проект по паспорту «не хранит записи как архив».
|
||||
|
||||
Найдено проходом `review-specs` ревью дизайна change
|
||||
`2026-08-11-fix-http-handler-tests`; отчёт триажа —
|
||||
`openspec/changes/archive/2026-08-11-fix-http-handler-tests/review/triage.md`.
|
||||
Вынесено сюда решением человека на контрольной точке.
|
||||
|
||||
## Воспроизведение
|
||||
|
||||
Асимметрия видна в самом коде:
|
||||
|
||||
```
|
||||
sed -n '110,160p' internal/service/transcribe.go
|
||||
```
|
||||
|
||||
Ветка `fileRepo.Create` (строки 152–157) содержит `os.Remove(storageFilePath)` с
|
||||
комментарием «Удаляем файл если не удалось создать запись в БД». Ветки
|
||||
`io.Copy`, `dst.Close` и `metaviewer.GetInfo` (строки 116–133) возвращают ошибку
|
||||
без уборки, хотя файл к этому моменту уже создан.
|
||||
|
||||
Прогоном: `TestCreateTranscribeJob_MetaViewerFailure` в
|
||||
`internal/controller/http/transcribe_test.go` доводит приём до этой ветки —
|
||||
после него в каталоге хранения лежит файл, а `countJobs` равен нулю.
|
||||
|
||||
## Затрагивает
|
||||
|
||||
- `internal/service/transcribe.go`, функция `createTranscribeJob` — три ветки
|
||||
отказа между созданием файла и заведением записи в учёте;
|
||||
- `internal/controller/http/transcribe_test.go` — случай отказа метаданных
|
||||
получает проверку на отсутствие файла;
|
||||
- раскладка `data/files` не меняется: имена и формат прежние.
|
||||
|
||||
## Критерии приёмки
|
||||
|
||||
- Отказ чтения метаданных не оставляет файла в каталоге хранения. Оракул — тест
|
||||
на подставном источнике, возвращающем ошибку: каталог пуст после запроса.
|
||||
- Отказ записи на диск на середине не оставляет частично записанного файла.
|
||||
Оракул — тест с источником данных, обрывающимся на середине чтения.
|
||||
- Уборка сама не заслоняет исходную ошибку: отправитель по-прежнему получает
|
||||
отказ, а причина уезжает в журнал. Оракул — тот же тест, код ответа и запись в
|
||||
перехваченном журнале.
|
||||
|
||||
## Рамки
|
||||
|
||||
Уборка файлов, осиротевших **до** этой правки, сюда не входит: их надо найти
|
||||
сверкой каталога с учётом, и это отдельная работа с боевыми данными.
|
||||
|
||||
Reference in New Issue
Block a user