уточнение диагностики отправки сообщения
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
2025-09-29 23:11:00 +03:00
parent a5d3b82092
commit 9a98cffe48
3 changed files with 240 additions and 27 deletions
+199 -10
View File
@@ -2125,13 +2125,13 @@
// Проверяем, что оба поля заполнены
if (!userId || !message) {
alert('Пожалуйста, заполните оба поля: ID пользователя и сообщение');
showTelegramError('Пожалуйста, заполните оба поля: ID пользователя и сообщение', 'VALIDATION_ERROR');
return;
}
// Проверяем, что user_id является числом
if (isNaN(userId)) {
alert('ID пользователя должен быть числом');
showTelegramError('ID пользователя должен быть числом', 'VALIDATION_ERROR');
return;
}
@@ -2141,6 +2141,11 @@
sendBtn.innerHTML = '<i class="fas fa-spinner fa-spin me-1"></i> Отправка...';
sendBtn.disabled = true;
// Скрываем предыдущие ошибки
hideTelegramError();
const startTime = Date.now();
try {
const response = await fetch(`http://localhost:${BOT_PORT}/send_message`, {
method: 'POST',
@@ -2154,19 +2159,63 @@
})
});
const result = await response.json();
const responseTime = Date.now() - startTime;
if (result.success) {
alert('Сообщение отправлено успешно!');
// Очищаем поля
document.getElementById('telegram-user-id').value = '';
document.getElementById('telegram-message').value = '';
if (response.ok) {
const result = await response.json();
if (result.success) {
showTelegramSuccess('Сообщение отправлено успешно!', responseTime);
// Очищаем поля
document.getElementById('telegram-user-id').value = '';
document.getElementById('telegram-message').value = '';
} else {
const errorCode = result.error_code || 'UNKNOWN_ERROR';
showTelegramError(`Ошибка отправки сообщения: ${result.error}`, 'API_ERROR', {
status: response.status,
responseTime: responseTime,
userId: userId,
errorCode: errorCode
});
}
} else {
alert('Ошибка отправки сообщения: ' + result.error);
// Обрабатываем HTTP ошибки
let errorText = '';
try {
const errorResult = await response.json();
errorText = errorResult.error || 'Неизвестная ошибка';
} catch (e) {
errorText = `HTTP ${response.status}: ${response.statusText}`;
}
showTelegramError(`Ошибка сервера: ${errorText}`, 'HTTP_ERROR', {
status: response.status,
statusText: response.statusText,
responseTime: responseTime,
userId: userId
});
}
} catch (error) {
const responseTime = Date.now() - startTime;
console.error('Ошибка при отправке сообщения:', error);
alert('Произошла ошибка при отправке сообщения. Проверьте консоль для подробностей.');
let errorType = 'NETWORK_ERROR';
let errorMessage = 'Ошибка сети при отправке сообщения';
if (error.name === 'TypeError' && error.message.includes('fetch')) {
errorMessage = 'Не удается подключиться к серверу бота. Проверьте, что бот запущен.';
errorType = 'CONNECTION_ERROR';
} else if (error.name === 'AbortError') {
errorMessage = 'Запрос был прерван по таймауту';
errorType = 'TIMEOUT_ERROR';
}
showTelegramError(errorMessage, errorType, {
errorName: error.name,
errorMessage: error.message,
responseTime: responseTime,
userId: userId
});
} finally {
// Восстанавливаем кнопку
sendBtn.innerHTML = originalText;
@@ -2174,6 +2223,146 @@
}
}
// Функция для показа успешного результата
function showTelegramSuccess(message, responseTime) {
const alertDiv = document.createElement('div');
alertDiv.className = 'alert alert-success alert-dismissible fade show position-fixed';
alertDiv.style.cssText = 'top: 20px; right: 20px; z-index: 9999; min-width: 300px;';
alertDiv.innerHTML = `
<div class="d-flex align-items-center">
<i class="fas fa-check-circle me-2"></i>
<div>
<strong>Успех!</strong><br>
${message}<br>
<small class="text-muted">Время ответа: ${responseTime}мс</small>
</div>
</div>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
`;
document.body.appendChild(alertDiv);
// Автоматически скрываем через 5 секунд
setTimeout(() => {
if (alertDiv.parentNode) {
alertDiv.remove();
}
}, 5000);
}
// Функция для показа ошибки с подробной диагностикой
function showTelegramError(message, errorType, details = {}) {
const alertDiv = document.createElement('div');
alertDiv.className = 'alert alert-danger alert-dismissible fade show position-fixed';
alertDiv.style.cssText = 'top: 20px; right: 20px; z-index: 9999; min-width: 400px; max-width: 600px;';
let diagnosticInfo = '';
let suggestions = '';
// Генерируем диагностическую информацию в зависимости от типа ошибки
switch (errorType) {
case 'VALIDATION_ERROR':
suggestions = '<strong>Решение:</strong> Проверьте правильность введенных данных';
break;
case 'API_ERROR':
diagnosticInfo = `
<div class="mt-2">
<small class="text-muted">
<strong>Диагностика:</strong><br>
• Статус: ${details.status || 'N/A'}<br>
• Время ответа: ${details.responseTime || 'N/A'}мс<br>
• ID пользователя: ${details.userId || 'N/A'}<br>
• Код ошибки: ${details.errorCode || 'N/A'}
</small>
</div>
`;
// Специфичные предложения в зависимости от кода ошибки
switch (details.errorCode) {
case 'INVALID_TOKEN':
suggestions = '<strong>Решение:</strong> Проблема с аутентификацией. Проверьте настройки токена в системе.';
break;
case 'NO_DATA':
case 'NO_USER_ID':
case 'NO_MESSAGE':
case 'INVALID_USER_ID':
suggestions = '<strong>Решение:</strong> Проверьте правильность заполнения полей формы.';
break;
case 'TELEGRAM_ERROR':
suggestions = '<strong>Возможные причины:</strong><br>• Пользователь заблокировал бота<br>• Неверный ID пользователя<br>• Пользователь не начал диалог с ботом<br>• Превышен лимит отправки сообщений';
break;
case 'INTERNAL_ERROR':
suggestions = '<strong>Решение:</strong> Внутренняя ошибка сервера. Проверьте логи бота или обратитесь к администратору.';
break;
default:
suggestions = '<strong>Возможные причины:</strong><br>• Пользователь заблокировал бота<br>• Неверный ID пользователя<br>• Пользователь не начал диалог с ботом';
}
break;
case 'HTTP_ERROR':
diagnosticInfo = `
<div class="mt-2">
<small class="text-muted">
<strong>Диагностика:</strong><br>
• HTTP статус: ${details.status || 'N/A'} ${details.statusText || ''}<br>
• Время ответа: ${details.responseTime || 'N/A'}мс<br>
• ID пользователя: ${details.userId || 'N/A'}
</small>
</div>
`;
if (details.status === 401) {
suggestions = '<strong>Решение:</strong> Проблема с аутентификацией. Проверьте настройки токена.';
} else if (details.status === 500) {
suggestions = '<strong>Решение:</strong> Внутренняя ошибка сервера. Проверьте логи бота.';
} else {
suggestions = '<strong>Решение:</strong> Проверьте статус сервера и настройки подключения.';
}
break;
case 'CONNECTION_ERROR':
suggestions = '<strong>Решение:</strong><br>• Проверьте, что бот запущен на порту ' + BOT_PORT + '<br>• Проверьте сетевые настройки<br>• Убедитесь, что сервер доступен';
break;
case 'TIMEOUT_ERROR':
suggestions = '<strong>Решение:</strong> Попробуйте еще раз или проверьте стабильность соединения';
break;
case 'NETWORK_ERROR':
suggestions = '<strong>Решение:</strong> Проверьте интернет-соединение и доступность сервера';
break;
}
alertDiv.innerHTML = `
<div class="d-flex align-items-start">
<i class="fas fa-exclamation-triangle me-2 mt-1"></i>
<div class="flex-grow-1">
<strong>Ошибка отправки сообщения</strong><br>
${message}
${diagnosticInfo}
<div class="mt-2">
${suggestions}
</div>
</div>
</div>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
`;
document.body.appendChild(alertDiv);
// Автоматически скрываем через 10 секунд для ошибок
setTimeout(() => {
if (alertDiv.parentNode) {
alertDiv.remove();
}
}, 10000);
}
// Функция для скрытия ошибок
function hideTelegramError() {
const existingAlerts = document.querySelectorAll('.alert.position-fixed');
existingAlerts.forEach(alert => alert.remove());
}
// Добавляем обработчик события для кнопки отправки
document.getElementById('send-telegram-btn').addEventListener('click', sendTelegramMessage);