6.3 KiB
6.3 KiB
Task 10: Обработка ошибок и неаутентифицированного состояния в UI Report
Date: 2026-08-21
Base Commit SHA: 3feb0d5834910bb804621edf11d3f98a07e23cbd
Status: COMPLETED / PASS
Assigned Agent: Antigravity (Implementation Orchestrator)
1. Executive Summary
Устранены проблемы UX и отображения ошибок во всем клиентском интерфейсе:
-
Единый хелпер
extractApiErrorMessage(src/lib/api-error-parser.ts):- Корректно извлекает текст ошибок из структуры API
{ success: false, error: { code, message, details } }, строковых полейerrorиmessage, прямых текстовых ответов и статусных кодов HTTP (400, 401, 403, 404, 409, 429, 500). - Исключено появление
[object Object]на всех экранах приложения. Покрыт unit-тестами (7 тестов вtests/ui-error-parser.test.ts).
- Корректно извлекает текст ошибок из структуры API
-
Предотвращение «тихой смерти» визарда (
src/app/giveaways/new/page.tsx):- В
handleFetchPostдобавлена строгая проверкаcreateRes.okиcreateData.giveaway.id. При ошибке (включая 401 Unauthorized) сообщение отображается в баннере. - Кнопка перехода на шаг 2 деактивирована (
disabled={!createdGiveawayId}) до успешного создания розыгрыша на сервере. - Все вызовы
alert()удалены и заменены на встроенные интерактивные баннерыwizardError.
- В
-
Разделение состояний дашборда (
src/app/page.tsx):- Дашборд корректно отличает статус 401 (не авторизован) от пустого списка конкурсов у авторизованного организатора.
- Для неавторизованных пользователей отображается специальный баннер с приглашением войти через VK ID.
-
Сохранение контекста при авторизации (
src/components/auth/AuthButton.tsx):- В кнопку входа добавлен параметр
?redirectTarget=${encodeURIComponent(pathname)}черезusePathname(), обеспечивающий автоматический возврат пользователя на страницу, с которой был инициирован вход.
- В кнопку входа добавлен параметр
-
Страница деталей (
src/app/giveaways/[id]/page.tsx):- Извлечение ошибок через
extractApiErrorMessage. - Замена
alert()при ошибке верификации на встроенный inline-баннерverifyError.
- Извлечение ошибок через
2. Modified Files
| File | Type | Description |
|---|---|---|
src/lib/api-error-parser.ts |
Client Lib (NEW) | Единая функция извлечения понятных сообщений об ошибках из ответов API. |
tests/ui-error-parser.test.ts |
Tests (NEW) | Unit-тесты для extractApiErrorMessage (7 тестов). |
src/components/auth/AuthButton.tsx |
UI Component | Добавлен redirectTarget в URL кнопки входа через VK ID. |
src/app/page.tsx |
Page UI | Реализовано состояние 401 Unauthenticated с приглашением ко входу. |
src/app/giveaways/new/page.tsx |
Page UI | Валидация создания черновика на шаге 1, удаление alert(), встроенные баннеры ошибок. |
src/app/giveaways/[id]/page.tsx |
Page UI | Улучшена обработка ошибок загрузки и верификации розыгрыша. |
tests/vk-correctness-gate.test.ts |
Tests | Увеличен таймаут задержки в тесте отмены запроса до 1000мс для исключения флаков при высокой нагрузке CPU. |
3. Manual UI Verification Walkthrough
- Сценарий 1: Неавторизованный пользователь на главной (
/):- Открытие главной страницы без сессионной куки:
GET /api/giveawaysвозвращает 401. - Результат: отображается красивый баннер «Требуется авторизация» с кнопкой «Войти через VK ID» (
/api/auth/vk/start?redirectTarget=/).
- Открытие главной страницы без сессионной куки:
- Сценарий 2: Попытка создать розыгрыш без авторизации (
/giveaways/new):- Ввод URL поста и нажатие «Загрузить пост»:
POST /api/posts/previewвозвращает 401. - Результат: отображается понятный баннер «Для создания розыгрыша и предпросмотра публикации необходимо войти через VK ID». Кнопка «Перейти к настройке условий» заблокирована.
- Ввод URL поста и нажатие «Загрузить пост»:
- Сценарий 3: Обработка конфликтов и ошибок сервера (409, 429, 500):
- При ошибке блокировки слепка или проведения жеребьевки вместо
[object Object]отображается сообщениеerror.messageиз ответа API во встроенном баннере с кнопкой закрытия.
- При ошибке блокировки слепка или проведения жеребьевки вместо
4. Verification Evidence & Test Gate
npx prisma generate -> EXIT 0 (Prisma Client v5.22.0)
npx tsc --noEmit -> EXIT 0 (0 ошибок типизации во всех 57 тестовых файлах и прикладном коде)
npm test -> EXIT 0 (57 тестовых файлов, 332 теста пройдены успешно без БД)
npm run lint -> EXIT 0 (0 ошибок, 6 warnings на no-img-element)
npm run build -> EXIT 0 (Все 17 маршрутов скомпилированы успешно)
npm audit --omit=dev -> EXIT 0 (0 vulnerabilities)