# ⚡ Быстрый старт - Обработка ошибок ## 5-минутное руководство по использованию новой системы обработки ошибок --- ## 🎯 Основные сценарии ### 1️⃣ Простая загрузка данных ```jsx import { useErrorHandler } from '../hooks/useErrorHandler'; import api from '../lib/api'; function MyComponent() { const { withErrorHandler } = useErrorHandler(); const loadData = withErrorHandler( async () => { const response = await api.get('/domains-new'); setData(response.data); }, { successMessage: 'Данные загружены' } ); return ; } ``` **Что происходит:** - ✅ Автоматический retry при сбоях (до 3 раз) - ✅ User-friendly сообщения об ошибках - ✅ Успешное уведомление при загрузке - ✅ Нет дубликатов уведомлений --- ### 2️⃣ Кнопка с retry ```jsx import RetryButton from '../components/RetryButton'; import api from '../lib/api'; function MyComponent() { const [loading, setLoading] = useState(false); const saveData = async () => { setLoading(true); try { await api.post('/domains-new', { domains: [...] }); } finally { setLoading(false); } }; return ( Сохранить ); } ``` **Что происходит:** - ✅ Показывает индикатор загрузки - ✅ Автоматический retry при ошибках - ✅ Блокирует повторные клики --- ### 3️⃣ Ручная обработка ошибок ```jsx import { useErrorHandler } from '../hooks/useErrorHandler'; import api from '../lib/api'; function MyComponent() { const { handleError, handleSuccess } = useErrorHandler(); const deleteItem = async (id) => { try { await api.delete(`/domains-new/${id}`); handleSuccess('Домен удалён'); } catch (error) { handleError(error, { component: 'MyComponent', action: 'delete', itemId: id }); } }; return ; } ``` **Что происходит:** - ✅ Полный контроль над обработкой - ✅ Контекст для отладки - ✅ User-friendly сообщения --- ## 🔧 Настройка (уже сделано!) Все компоненты уже интегрированы в `App.jsx`: ```jsx {/* Ловит ошибки React */} {/* Мониторит сеть */} ``` Ничего дополнительно настраивать не нужно! 🎉 --- ## 📦 Что уже работает автоматически ### ✅ Автоматический Retry | Метод | Ошибка | Попытки | |-------|--------|---------| | GET | Network | 3 | | GET | Timeout | 2 | | GET | Server (5xx) | 2 | | POST/PUT | Network | 1 | | POST/PUT | Timeout | 1 | ### ✅ User-Friendly сообщения **Технические ошибки** → **Понятные сообщения** - `ECONNABORTED` → "Сервер не отвечает" - `500 Internal Server Error` → "Ошибка сервера. Попробуйте позже" - `400 Bad Request` → "Ошибка валидации. Проверьте данные" - `404 Not Found` → "Запрашиваемый ресурс не найден" ### ✅ Offline Detection - Красный баннер при потере связи - Зелёный баннер при восстановлении - Автоматическое скрытие через 3 секунды ### ✅ Error Boundary - Ловит ошибки рендеринга React - Показывает красивую страницу ошибки - Кнопки восстановления --- ## 🎨 Типы уведомлений ```jsx const { handleSuccess, handleError, handleWarning, handleInfo } = useErrorHandler(); handleSuccess('Данные сохранены'); // 🟢 Зелёное handleError('Не удалось загрузить'); // 🔴 Красное handleWarning('Изменения не сохранены'); // 🟡 Жёлтое handleInfo('Проверьте обновления'); // 🔵 Синее ``` --- ## 🚀 Продвинутые примеры ### React Query интеграция ```jsx import { useQuery } from '@tanstack/react-query'; import { useErrorHandler } from '../hooks/useErrorHandler'; import api from '../lib/api'; function MyComponent() { const { handleError } = useErrorHandler(); const { data, isLoading, refetch } = useQuery({ queryKey: ['domains'], queryFn: async () => { const res = await api.get('/domains-new'); return res.data; }, onError: (error) => { handleError(error, { query: 'domains' }); }, retry: 3 // React Query также делает retry }); return
{/* ... */}
; } ``` ### Условная обработка ```jsx import { useErrorHandler } from '../hooks/useErrorHandler'; import { isCriticalError } from '../lib/api'; import api from '../lib/api'; function MyComponent() { const { handleError } = useErrorHandler(); const loadData = async () => { try { const res = await api.get('/critical-data'); setData(res.data); } catch (error) { if (isCriticalError(error)) { // Критичная ошибка - перенаправить handleError(error); navigate('/error'); } else { // Некритичная - показать уведомление handleError(error); } } }; return ; } ``` ### Batch операции ```jsx import { useErrorHandler } from '../hooks/useErrorHandler'; import api from '../lib/api'; function MyComponent() { const { handleError, handleSuccess } = useErrorHandler(); const deleteMultiple = async (ids) => { const errors = []; for (const id of ids) { try { await api.delete(`/domains-new/${id}`); } catch (error) { errors.push({ id, error }); } } if (errors.length === 0) { handleSuccess(`Удалено ${ids.length} элементов`); } else { handleError(new Error(`Не удалось удалить ${errors.length} элементов`), { errors }); } }; return ; } ``` --- ## 📚 Дополнительная документация - **Полное руководство:** [ERROR_HANDLING_GUIDE.md](./ERROR_HANDLING_GUIDE.md) - **Схемы работы:** [ERROR_HANDLING_FLOW.md](./ERROR_HANDLING_FLOW.md) - **Примеры кода:** [frontend/src/examples/ErrorHandlingExample.jsx](./frontend/src/examples/ErrorHandlingExample.jsx) - **Краткое резюме:** [ERROR_HANDLING_SUMMARY.md](./ERROR_HANDLING_SUMMARY.md) --- ## 🐛 Отладка ### Посмотреть детали ошибки В уведомлении кликните **"Подробнее"**: ``` Детали: { "type": "NETWORK", "status": null, "message": "Не удалось подключиться к серверу", "requestId": "abc123", "url": "/api/domains-new", "method": "GET", "timestamp": "2025-10-03T15:30:45.123Z", "action": "Проверьте подключение к интернету" } ``` ### Консоль браузера Все ошибки логируются в консоль: ```javascript // Открыть DevTools (F12) → Console console.error('API Error:', { type: 'NETWORK', retryAttempt: 3, maxRetries: 3, // ... }); ``` ### Очистить кэш ```javascript // В консоли браузера localStorage.clear(); sessionStorage.clear(); window.location.reload(); ``` --- ## ❓ FAQ **Q: Нужно ли обрабатывать каждую ошибку вручную?** A: Нет! API автоматически показывает уведомления. Используйте `handleError` только для локальной логики. **Q: Как отключить автоматические уведомления?** A: Используйте `withErrorHandler` с опцией `silent: true`: ```jsx withErrorHandler(fn, { silent: true }) ``` **Q: Как изменить количество retry попыток?** A: Отредактируйте `frontend/src/lib/apiErrorHandler.js` → `getMaxRetries()` **Q: Работает ли offline?** A: Частично. Приложение детектирует offline, но не сохраняет данные локально. Это можно добавить позже. **Q: Как интегрировать с Sentry?** A: См. [ERROR_HANDLING_GUIDE.md](./ERROR_HANDLING_GUIDE.md) → Раздел "Настройка" --- ## ✅ Чек-лист интеграции - [x] ErrorBoundary добавлен в App.jsx - [x] NetworkErrorHandler добавлен в App.jsx - [x] api.js обновлён с улучшенным retry - [x] useErrorHandler хук создан - [x] RetryButton компонент создан - [x] apiErrorHandler утилиты созданы - [x] Документация написана - [x] Примеры кода добавлены - [x] Линтер проверки пройдены **Статус: ✅ Готово к использованию!** --- ## 🎉 Начните использовать прямо сейчас! 1. Запустите приложение: ```powershell cd backend && npm start cd frontend && npm run dev ``` 2. Импортируйте хук в любой компонент: ```jsx import { useErrorHandler } from '../hooks/useErrorHandler'; ``` 3. Используйте `withErrorHandler` или `handleError` 4. Наслаждайтесь автоматической обработкой ошибок! 🚀 --- **Вопросы?** → [ERROR_HANDLING_GUIDE.md](./ERROR_HANDLING_GUIDE.md) **Проблемы?** → Проверьте консоль браузера **Идеи?** → Создайте issue или PR