From 90ab969de0bab33c665d36af9faa6acb9293c5d6 Mon Sep 17 00:00:00 2001 From: AI Assistant Date: Tue, 28 Oct 2025 00:47:03 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D0=BB=D0=BE=D0=B3=20=D1=81=D0=B5=D1=81=D1=81?= =?UTF-8?q?=D0=B8=D0=B8=20=D0=BE=D1=82=2028.10.2025=20-=20=D0=B8=D1=81?= =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20SSE=20?= =?UTF-8?q?error=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SESSION_LOG_2025-10-28.md | 356 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 356 insertions(+) create mode 100644 SESSION_LOG_2025-10-28.md diff --git a/SESSION_LOG_2025-10-28.md b/SESSION_LOG_2025-10-28.md new file mode 100644 index 0000000..77c2e14 --- /dev/null +++ b/SESSION_LOG_2025-10-28.md @@ -0,0 +1,356 @@ +# 📋 Лог сессии: Исправление SSE error handling + +**Дата:** 28 октября 2025 (00:00 - 01:00 MSK) +**Задача:** Исправление ошибки "Ошибка подключения к серверу" при успешном распознавании полиса +**Статус:** ✅ Успешно завершено + +--- + +## 🎯 Проблема + +После успешного распознавания полиса через OCR/Vision, пользователь видел модальное окно с ошибкой: +``` +❌ Ошибка распознавания +Ошибка подключения к серверу + +Полный ответ: null +``` + +Хотя в логах backend видно, что: +- ✅ SSE подключение установлено +- ✅ Событие OCR получено из Redis +- ✅ Данные отправлены клиенту +- ✅ SSE соединение закрыто корректно + +--- + +## 🔍 Диагностика + +### Backend логи показывали успешную работу: + +``` +2025-10-28 00:41:15,187 - 🚀 SSE connection requested for task_id: CLM-2025-10-27-Y1KWA1 +2025-10-28 00:41:15,202 - 📡 Client subscribed to ocr_events:CLM-2025-10-27-Y1KWA1 +2025-10-28 00:41:15,203 - ⏳ Waiting for message on ocr_events:CLM-2025-10-27-Y1KWA1... +2025-10-28 00:41:49,729 - 📥 Received message type: message +2025-10-28 00:41:49,729 - 📦 Raw event data: {"claim_id":"CLM-2025-10-27-Y1KWA1","event":{"event_type":"ocr_completed","status":"completed","message":"OCR обработка завершена","data":{"output":{"is_policy":"yes","policy_number":"E1000-302545808"... +2025-10-28 00:41:49,730 - 📦 Unwrapped n8n Redis format for CLM-2025-10-27-Y1KWA1 +2025-10-28 00:41:49,730 - 📤 Sending event to client: completed +2025-10-28 00:41:49,730 - ✅ Task CLM-2025-10-27-Y1KWA1 finished, closing SSE +``` + +**Вывод:** Backend работал корректно! + +### Причина ошибки: + +1. Backend отправляет событие OCR клиенту +2. Backend **закрывает SSE соединение** (это нормально) +3. Браузер получает событие закрытия SSE +4. Браузер триггерит `eventSource.onerror` +5. Frontend в `onerror` **перезаписывает успешный результат** ошибкой: + +```typescript +// ❌ СТАРЫЙ КОД (неправильный) +eventSource.onerror = (error) => { + console.error('❌ SSE connection error:', error); + setOcrModalContent({ + success: false, + data: null, + message: 'Ошибка подключения к серверу' + }); + setWaitingForOcr(false); + eventSource.close(); +}; +``` + +**Проблема:** `onerror` вызывается **после** получения результата, когда backend закрывает SSE, и затирает успешный результат. + +--- + +## 🛠️ Решение + +Добавил проверку в `eventSource.onerror` — если уже получили результат OCR, не затираем его сообщением об ошибке: + +```typescript +// ✅ НОВЫЙ КОД (правильный) +eventSource.onerror = (error) => { + console.error('❌ SSE connection error:', error); + console.error('SSE readyState:', eventSource.readyState); + + // Не показываем ошибку если уже получили результат (backend закрыл SSE после успешной отправки) + setOcrModalContent((prev) => { + if (prev && prev !== 'loading') { + console.log('✅ SSE закрыто после получения результата, не показываем ошибку'); + return prev; // Оставляем текущий результат + } + return { success: false, data: null, message: 'Ошибка подключения к серверу' }; + }); + + setWaitingForOcr(false); + eventSource.close(); +}; +``` + +**Логика:** +- Если `prev !== 'loading'` → значит уже получили результат → **не затираем** его +- Если `prev === 'loading'` → реальная ошибка подключения → показываем ошибку + +--- + +## 📝 Изменённые файлы + +### `/frontend/src/components/form/Step1Policy.tsx` + +**Изменение:** Обработка `eventSource.onerror` с проверкой наличия результата + +**Строки:** 147-162 + +**Было:** +```typescript +eventSource.onerror = (error) => { + console.error('❌ SSE connection error:', error); + setOcrModalContent({ success: false, data: null, message: 'Ошибка подключения к серверу' }); + setWaitingForOcr(false); + eventSource.close(); +}; +``` + +**Стало:** +```typescript +eventSource.onerror = (error) => { + console.error('❌ SSE connection error:', error); + console.error('SSE readyState:', eventSource.readyState); + + setOcrModalContent((prev) => { + if (prev && prev !== 'loading') { + console.log('✅ SSE закрыто после получения результата, не показываем ошибку'); + return prev; + } + return { success: false, data: null, message: 'Ошибка подключения к серверу' }; + }); + + setWaitingForOcr(false); + eventSource.close(); +}; +``` + +--- + +## 🐛 Проблемы в процессе исправления + +### Проблема 1: Backend завис после kill -HUP + +**Симптом:** +```bash +ERROR: [Errno 98] Address already in use +``` + +**Причина:** `kill -HUP` не перезапустил uvicorn корректно, порт 8100 остался занят зависшим процессом. + +**Решение:** +```bash +# Убили все процессы на порту 8100 +sudo lsof -ti :8100 | xargs -r kill -9 + +# Перезапустили backend +cd /var/www/fastuser/data/www/crm.clientright.ru/erv_platform/backend +source venv/bin/activate +python -m uvicorn app.main:app --host 0.0.0.0 --port 8100 --reload > ../backend.log 2>&1 & +``` + +### Проблема 2: Изменения не применились во frontend + +**Симптом:** После `docker-compose restart frontend` старый код всё ещё работал. + +**Причина:** Frontend работает в Docker без volume mount — код встроен в образ при сборке. + +**Решение:** +```bash +# Пересборка образа с новым кодом +docker-compose build frontend + +# Пересоздание контейнера +docker-compose up -d frontend +``` + +**Проверка применения изменений:** +```bash +docker exec erv_platform_frontend_1 grep -A8 "eventSource.onerror" /app/src/components/form/Step1Policy.tsx +``` + +--- + +## 🚀 Git Commit + +**Commit:** `0b75e01` +**Message:** "fix: Не затираем результат OCR при закрытии SSE соединения" + +**Полное описание:** +``` +Проблема: Backend закрывает SSE после отправки события, браузер триггерит onerror, +фронтенд перезаписывал успешный результат сообщением 'Ошибка подключения к серверу'. + +Решение: Проверяем в onerror что если уже получили результат (prev !== 'loading'), +не затираем его ошибкой. +``` + +**Push:** ✅ `origin/main` + +--- + +## ✅ Результат + +### Что работает: +1. ✅ Backend запущен (PID 25931) на порту 8100 +2. ✅ Frontend пересобран и работает на http://147.45.146.17:5173 +3. ✅ SSE подключение устанавливается корректно +4. ✅ События OCR получаются из Redis через backend +5. ✅ Результат распознавания отображается в модальном окне +6. ✅ **Ошибка "Ошибка подключения к серверу" больше не появляется** +7. ✅ Git репозиторий синхронизирован + +### Тестирование: + +**Сценарий 1: Успешное распознавание полиса** +- Загрузка файла полиса → ✅ +- SSE подключение → ✅ +- OCR/Vision обработка → ✅ +- Отображение результата → ✅ "Полис распознан: E1000-302545808" +- **Нет ошибки** при закрытии SSE → ✅ + +**Сценарий 2: Загрузка неподходящего документа** +- Загрузка не-полиса → ✅ +- SSE подключение → ✅ +- OCR/Vision обработка → ✅ +- Отображение: "Документ не является полисом ERV" → ✅ + +**Сценарий 3: Реальная ошибка подключения** +- Если backend недоступен → ❌ "Ошибка подключения к серверу" (корректная ошибка) + +--- + +## 📊 Архитектура (финальная) + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ USER BROWSER │ +│ │ +│ ┌──────────────────────────────────────────────────────────────┐ │ +│ │ React Frontend (Vite Dev Server, port 3000) │ │ +│ │ - Step1Policy.tsx (SSE Client) │ │ +│ │ - Модалка с результатом OCR │ │ +│ │ - EventSource(`/events/${claimId}`) │ │ +│ │ - ✅ Защита от затирания результата в onerror │ │ +│ └────────────┬─────────────────────────────────────────────────┘ │ +│ │ Vite Proxy (/events → host:8100) │ +└───────────────┼─────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────────┐ +│ BACKEND (FastAPI, port 8100) │ +│ PID: 25931 │ +│ ┌──────────────────────────────────────────────────────────────┐ │ +│ │ SSE Endpoint: GET /events/{task_id} │ │ +│ │ - Подписка на Redis: ocr_events:{task_id} │ │ +│ │ - Стриминг событий через SSE │ │ +│ │ - Закрытие SSE после отправки результата │ │ +│ └────────────┬─────────────────────────────────────────────────┘ │ +└───────────────┼──────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────────┐ +│ Redis Pub/Sub (crm.clientright.ru:6379) │ +│ │ +│ Channel: ocr_events:CLM-2025-10-27-XXXXX │ +│ Format: { │ +│ "claim_id": "CLM-...", │ +│ "event": { │ +│ "event_type": "ocr_completed", │ +│ "status": "completed", │ +│ "data": { "output": { "is_policy": "yes", ... } } │ +│ } │ +│ } │ +└────────────────▲────────────────────────────────────────────────────┘ + │ + │ PUBLISH + │ +┌────────────────┴────────────────────────────────────────────────────┐ +│ n8n Workflow (OCR Processing) │ +│ │ +│ 1. Webhook trigger (file upload) │ +│ 2. Upload to S3 │ +│ 3. OCR Service (147.45.146.17:8001) │ +│ 4. AI Vision (OpenRouter Gemini 2.0 Flash) │ +│ 5. Redis Publish Node → ocr_events:{claim_id} │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 📈 Метрики + +**Время выполнения сессии:** ~1 час +**Количество коммитов:** 1 +**Изменённых файлов:** 1 +**Строк изменено:** +10 / -1 +**Перезапусков backend:** 2 +**Rebuild frontend:** 1 + +**Проблемы решены:** +- ✅ Затирание результата OCR при закрытии SSE +- ✅ Backend завис после kill -HUP +- ✅ Изменения не применялись без rebuild + +--- + +## 🔗 Ссылки + +- Frontend: http://147.45.146.17:5173 +- Backend API: http://localhost:8100 +- Backend Health: http://localhost:8100/health +- Gitea: http://147.45.146.17:3002/negodiy/erv-platform +- n8n: http://147.45.146.17:5678 + +--- + +## 📝 Важные заметки + +### Backend запущен вне Docker: +```bash +# Процесс +PID: 25931 +Command: python -m uvicorn app.main:app --host 0.0.0.0 --port 8100 --reload + +# Логи +tail -f /var/www/fastuser/data/www/crm.clientright.ru/erv_platform/backend.log + +# Перезапуск +cd /var/www/fastuser/data/www/crm.clientright.ru/erv_platform/backend +source venv/bin/activate +python -m uvicorn app.main:app --host 0.0.0.0 --port 8100 --reload > ../backend.log 2>&1 & +``` + +### Frontend требует rebuild при изменениях: +```bash +# Применение изменений +docker-compose build frontend +docker-compose up -d frontend + +# Проверка кода в контейнере +docker exec erv_platform_frontend_1 cat /app/src/components/form/Step1Policy.tsx +``` + +### Redis credentials: +``` +Host: crm.clientright.ru +Port: 6379 +Password: cKSq8M11ZQIRi59OuUXb +Channels: ocr_events:{claim_id} +``` + +--- + +**Статус:** ✅ Успешно завершено +**Автор:** AI Assistant (Claude Sonnet 4.5) +**Дата:** 28 октября 2025, 01:00 MSK +