219 lines
7.1 KiB
React
219 lines
7.1 KiB
React
/**
|
||
* Примеры использования новой системы обработки ошибок
|
||
* Этот файл демонстрирует различные сценарии использования
|
||
*/
|
||
|
||
import { useState } from 'react';
|
||
import { useErrorHandler } from '../hooks/useErrorHandler';
|
||
import RetryButton from '../components/RetryButton';
|
||
import api from '../lib/api';
|
||
|
||
/**
|
||
* Пример 1: Простая обработка ошибок в компоненте
|
||
*/
|
||
function SimpleErrorHandlingExample() {
|
||
const [data, setData] = useState(null);
|
||
const [loading, setLoading] = useState(false);
|
||
const { handleError, handleSuccess, withErrorHandler } = useErrorHandler();
|
||
|
||
// Вариант 1: Ручная обработка ошибок
|
||
const fetchDataManual = async () => {
|
||
setLoading(true);
|
||
try {
|
||
const response = await api.get('/domains-new');
|
||
setData(response.data);
|
||
handleSuccess('Данные успешно загружены');
|
||
} catch (error) {
|
||
handleError(error, { component: 'SimpleErrorHandlingExample' });
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
};
|
||
|
||
// Вариант 2: Автоматическая обработка с withErrorHandler
|
||
const fetchDataAuto = withErrorHandler(
|
||
async () => {
|
||
setLoading(true);
|
||
const response = await api.get('/domains-new');
|
||
setData(response.data);
|
||
setLoading(false);
|
||
},
|
||
{
|
||
successMessage: 'Данные успешно загружены',
|
||
context: { component: 'SimpleErrorHandlingExample' }
|
||
}
|
||
);
|
||
|
||
return (
|
||
<div className="card">
|
||
<div className="card-header">
|
||
<h3 className="card-title">Пример простой обработки ошибок</h3>
|
||
</div>
|
||
<div className="card-body">
|
||
<div className="btn-list">
|
||
<button
|
||
className="btn btn-primary"
|
||
onClick={fetchDataManual}
|
||
disabled={loading}
|
||
>
|
||
Загрузить (ручная обработка)
|
||
</button>
|
||
<button
|
||
className="btn btn-primary"
|
||
onClick={fetchDataAuto}
|
||
disabled={loading}
|
||
>
|
||
Загрузить (автоматическая обработка)
|
||
</button>
|
||
</div>
|
||
{data && (
|
||
<div className="mt-3">
|
||
<p>Загружено записей: {data.items?.length || 0}</p>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Пример 2: Использование RetryButton
|
||
*/
|
||
function RetryButtonExample() {
|
||
const [attempts, setAttempts] = useState(0);
|
||
const { handleError: _handleError, handleSuccess } = useErrorHandler();
|
||
|
||
const unreliableOperation = async () => {
|
||
setAttempts(prev => prev + 1);
|
||
|
||
// Симуляция операции которая иногда падает
|
||
if (Math.random() < 0.5) {
|
||
throw new Error('Случайная ошибка для демонстрации');
|
||
}
|
||
|
||
handleSuccess('Операция выполнена успешно!');
|
||
};
|
||
|
||
return (
|
||
<div className="card">
|
||
<div className="card-header">
|
||
<h3 className="card-title">Пример использования RetryButton</h3>
|
||
</div>
|
||
<div className="card-body">
|
||
<p>Попыток: {attempts}</p>
|
||
<RetryButton
|
||
onRetry={unreliableOperation}
|
||
className="btn btn-primary"
|
||
>
|
||
Выполнить ненадежную операцию
|
||
</RetryButton>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Пример 3: Обработка различных типов ошибок
|
||
*/
|
||
function ErrorTypesExample() {
|
||
const { handleError } = useErrorHandler();
|
||
|
||
const triggerNetworkError = () => {
|
||
api.get('/nonexistent-endpoint')
|
||
.catch(error => handleError(error));
|
||
};
|
||
|
||
const triggerValidationError = () => {
|
||
api.post('/domains-new', { invalid: 'data' })
|
||
.catch(error => handleError(error));
|
||
};
|
||
|
||
const triggerTimeoutError = () => {
|
||
// Создаем запрос который точно превысит таймаут
|
||
const slowApi = api.create({ timeout: 100 });
|
||
slowApi.get('/domains-new')
|
||
.catch(error => handleError(error));
|
||
};
|
||
|
||
return (
|
||
<div className="card">
|
||
<div className="card-header">
|
||
<h3 className="card-title">Типы ошибок</h3>
|
||
</div>
|
||
<div className="card-body">
|
||
<div className="btn-list">
|
||
<button
|
||
className="btn btn-danger"
|
||
onClick={triggerNetworkError}
|
||
>
|
||
Сетевая ошибка
|
||
</button>
|
||
<button
|
||
className="btn btn-warning"
|
||
onClick={triggerValidationError}
|
||
>
|
||
Ошибка валидации
|
||
</button>
|
||
<button
|
||
className="btn btn-info"
|
||
onClick={triggerTimeoutError}
|
||
>
|
||
Таймаут
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Главный компонент с примерами
|
||
*/
|
||
function ErrorHandlingExample() {
|
||
return (
|
||
<div className="container-xl">
|
||
<div className="page-header">
|
||
<h1 className="page-title">Примеры обработки ошибок</h1>
|
||
<p className="text-muted">
|
||
Демонстрация возможностей новой системы обработки ошибок
|
||
</p>
|
||
</div>
|
||
|
||
<div className="row row-cards">
|
||
<div className="col-12">
|
||
<SimpleErrorHandlingExample />
|
||
</div>
|
||
<div className="col-12">
|
||
<RetryButtonExample />
|
||
</div>
|
||
<div className="col-12">
|
||
<ErrorTypesExample />
|
||
</div>
|
||
</div>
|
||
|
||
<div className="card mt-3">
|
||
<div className="card-header">
|
||
<h3 className="card-title">Особенности новой системы</h3>
|
||
</div>
|
||
<div className="card-body">
|
||
<ul>
|
||
<li>✅ <strong>Автоматический retry</strong> для GET запросов (до 3 попыток)</li>
|
||
<li>✅ <strong>Умный retry</strong> для POST/PUT/DELETE при сетевых ошибках</li>
|
||
<li>✅ <strong>Exponential backoff</strong> с jitter для избежания thundering herd</li>
|
||
<li>✅ <strong>User-friendly сообщения</strong> вместо технических ошибок</li>
|
||
<li>✅ <strong>Детальная информация</strong> для отладки (requestId, timestamp, детали)</li>
|
||
<li>✅ <strong>Offline/Online detection</strong> с уведомлениями</li>
|
||
<li>✅ <strong>Error Boundary</strong> для ловли React ошибок рендеринга</li>
|
||
<li>✅ <strong>Типизация ошибок</strong> (Network, Timeout, Server, Client, etc.)</li>
|
||
<li>✅ <strong>Интеграция с системой уведомлений</strong></li>
|
||
<li>✅ <strong>Логирование критичных ошибок</strong></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
export default ErrorHandlingExample;
|
||
|