Merge dev: Add API improvements (timeout, error handling, logging)
Some checks are pending
CI/CD / lint-and-build (push) Waiting to run

This commit is contained in:
DosAi 2025-11-02 17:19:41 +03:00
commit abc35ad0ca
2 changed files with 43 additions and 5 deletions

View File

@ -35,7 +35,7 @@ router.post(
.isNumeric()
.withMessage('Value must be a number'),
],
validate, // Middleware для обработки ошибок валидации
validate, // Проверяем результаты валидации
(req, res) => {
try {
const { name, value } = req.body;

View File

@ -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,
};
}
}