# 🧹 Проверять ответ обработчика на отказ репозитория - **Тип:** chore - **Категория:** Очередь — Подставной репозиторий заводится там же, где тесты конвейера: одна сборка теста на два слоя - **Зачем:** Тесты обработчиков идут по настоящему sqlite без управляемых отказов: класс «база недоступна во время запроса» не проверен нигде. - **Теги:** review-2026-08-23 Тесты обработчиков ходят по настоящему sqlite во временном каталоге. Управляемых отказов у него нет, поэтому весь класс «база недоступна во время запроса» не проверен нигде: что отвечает обработчик, когда репозиторий отказал, известно только чтением кода. Проверять надо не отказ базы, а ответ на него: код, тело единой формы и то, что причина не попала в ответ пользователю. Для этого репозиторию нужна подставная реализация, отказывающая по требованию. Гипотеза прохода `review-autotests` (A4) ревью change `2026-08-23-storage-without-pocketbase`, понижённая триажем до наблюдения: оракула у неё нет ровно потому, что управляемых отказов не существует. Сам пробел проверен — `grep` по тестам пакета пуст. ## Затрагивает - тесты `internal/controller/http` — сборка теста и способ подставить репозиторий; - договор ядра с хранилищем `internal/contract` — интерфейсы, по которым подставляется отказ; - единая форма ответа об отказе `internal/controller/http/errors.go`. ## Критерии приёмки - Тест подставляет отказ репозитория. **Оракул:** тест — подставной репозиторий отдаёт ошибку на названном методе, и обработчик её получает. - Ответ на отказ идёт единой формой и не несёт причины. **Оракул:** тест на каждом читающем обработчике — код `500`, тело эталонной формы, текста ошибки базы в теле нет. - Отказ виден владельцу сервиса. **Оракул:** тот же тест с перехваченным журналом — строка уровня `ERROR` с причиной есть. ## Рамки Настоящую базу из тестов не убираем: подставной репозиторий нужен для отказов, а не вместо неё. Формы ответов и коды не меняем — задача проверяет то, что уже объявлено.