- пять из урожая change 2026-08-11-fix-http-handler-tests, тег review-2026-08-11; утечка имени файла в журнал поставлена первой строкой очереди - опечатка transcibe дописана в json-api-for-spa: текст ошибки — часть необратимого контракта, и в одиночку он не правится
4.2 KiB
🐞 Убирать записанный файл, когда приём отказал на середине
- Тип: 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не меняется: имена и формат прежние.
Критерии приёмки
- Отказ чтения метаданных не оставляет файла в каталоге хранения. Оракул — тест на подставном источнике, возвращающем ошибку: каталог пуст после запроса.
- Отказ записи на диск на середине не оставляет частично записанного файла. Оракул — тест с источником данных, обрывающимся на середине чтения.
- Уборка сама не заслоняет исходную ошибку: отправитель по-прежнему получает отказ, а причина уезжает в журнал. Оракул — тот же тест, код ответа и запись в перехваченном журнале.
Рамки
Уборка файлов, осиротевших до этой правки, сюда не входит: их надо найти сверкой каталога с учётом, и это отдельная работа с боевыми данными.