feat: Add timeout, improved error handling and logging to API client
Some checks are pending
CI/CD / lint-and-build (push) Waiting to run
Some checks are pending
CI/CD / lint-and-build (push) Waiting to run
This commit is contained in:
parent
0fe27033b5
commit
766d758be1
@ -35,7 +35,7 @@ router.post(
|
||||
.isNumeric()
|
||||
.withMessage('Value must be a number'),
|
||||
],
|
||||
validate, // Middleware для обработки ошибок валидации
|
||||
validate, // Проверяем результаты валидации
|
||||
(req, res) => {
|
||||
try {
|
||||
const { name, value } = req.body;
|
||||
|
||||
@ -26,32 +26,70 @@ export async function apiRequest<T = unknown>(
|
||||
options: RequestInit = {}
|
||||
): Promise<ApiResponse<T>> {
|
||||
try {
|
||||
// Добавляем timeout через AbortController
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 секунд
|
||||
|
||||
console.log(`[API] Request to: ${apiUrl}/api/${endpoint}`);
|
||||
|
||||
const response = await fetch(`${apiUrl}/api/${endpoint}`, {
|
||||
...options,
|
||||
signal: controller.signal,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...options.headers,
|
||||
},
|
||||
});
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
|
||||
const data = await response.json();
|
||||
// Сначала читаем ответ как текст, потом парсим JSON
|
||||
const responseText = await response.text();
|
||||
let data: any;
|
||||
|
||||
if (responseText) {
|
||||
try {
|
||||
data = JSON.parse(responseText);
|
||||
} catch (jsonErr) {
|
||||
// Если не удалось распарсить JSON, возвращаем текст как ошибку
|
||||
console.error('Failed to parse JSON response:', responseText);
|
||||
return {
|
||||
success: false,
|
||||
error: `Invalid JSON response: ${responseText.substring(0, 100)}`,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
data = {};
|
||||
}
|
||||
|
||||
// Если статус не успешный, возвращаем данные с ошибкой
|
||||
// (могут содержать детали валидации)
|
||||
if (!response.ok) {
|
||||
return {
|
||||
success: false,
|
||||
error: data.error || `HTTP error! status: ${response.status}`,
|
||||
error: data.error || data.message || `HTTP error! status: ${response.status}`,
|
||||
errors: data.errors, // Ошибки валидации, если есть
|
||||
};
|
||||
}
|
||||
|
||||
return data;
|
||||
} catch (err) {
|
||||
console.error('API Error:', err);
|
||||
console.error('[API] Error:', err);
|
||||
let errorMessage = 'Unknown error';
|
||||
|
||||
if (err instanceof Error) {
|
||||
if (err.name === 'AbortError') {
|
||||
errorMessage = 'Request timeout - сервер не отвечает';
|
||||
} else if (err.message.includes('Failed to fetch')) {
|
||||
errorMessage = 'Не удалось подключиться к серверу. Проверьте, что бэкенд запущен.';
|
||||
} else {
|
||||
errorMessage = err.message;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: false,
|
||||
error: err instanceof Error ? err.message : 'Unknown error',
|
||||
error: errorMessage,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user