frontPanel/src/utils/handleComponentError.ts
Nastya e9b7f1b0a9
All checks were successful
Deploy / CreateImage (push) Successful in 5m58s
Deploy / DeployService (push) Successful in 30s
фикс подсчёта кол-ва непрочитанных
2025-07-24 02:41:58 +03:00

109 lines
4.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { ErrorInfo } from "react";
import { Ticket, createTicket, getAuthToken, sendTicketMessage } from "..";
let errorsQueue: ComponentError[] = [];
let timeoutId: ReturnType<typeof setTimeout>;
interface ComponentError {
timestamp: number;
message: string;
callStack: string | undefined;
componentStack: string | null | undefined;
}
function isErrorReportingAllowed(error?: Error): boolean {
// Если ошибка помечена как debug-override — всегда отправлять
if (error && (error as any).__forceSend) return true;
// Проверяем домен
const currentDomain = window.location.hostname;
return currentDomain !== 'localhost';
}
// Новый API: getTickets — callback, возвращающий актуальные тикеты
export function handleComponentError(error: Error, info: ErrorInfo, getTickets: () => Ticket[]) {
//репортим только о авторизонышах
if (!getAuthToken()) return;
// Проверяем разрешение на отправку ошибок (по домену)
if (!isErrorReportingAllowed(error)) {
console.log('❌ Отправка ошибки заблокирована:', error.message);
return;
}
console.log(`✅ Обработка ошибки: ${error.message}`);
// Копируем __forceSend если есть
const componentError: ComponentError & { __forceSend?: boolean } = {
timestamp: Math.floor(Date.now() / 1000),
message: error.message,
callStack: error.stack,
componentStack: info.componentStack,
...(error && (error as any).__forceSend ? { __forceSend: true } : {})
};
queueErrorRequest(componentError, getTickets);
}
// Ставит ошибку в очередь для отправки, через 1 секунду вызывает sendErrorsToServer
export function queueErrorRequest(error: ComponentError, getTickets: () => Ticket[]) {
errorsQueue.push(error);
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
sendErrorsToServer(getTickets);
}, 1000);
}
// Отправляет накопленные ошибки в тикеты, ищет существующий тикет с system: true или создает новый
export async function sendErrorsToServer(getTickets: () => Ticket[]) {
if (errorsQueue.length === 0) return;
// Проверяем разрешение на отправку ошибок (по домену и debug-override)
// Если хотя бы одна ошибка в очереди с __forceSend, отправляем всё
const forceSend = errorsQueue.some(e => (e as any).__forceSend);
if (!forceSend && !isErrorReportingAllowed()) {
console.log('❌ Отправка ошибок заблокирована, очищаем очередь');
errorsQueue = [];
return;
}
const tickets = getTickets();
try {
// Формируем сообщение об ошибке
const errorMessage = errorsQueue.map(error => {
return `[${new Date(error.timestamp * 1000).toISOString()}] ${error.message}\n\nCall Stack:\n${error.callStack || 'N/A'}\n\nComponent Stack:\n${error.componentStack || 'N/A'}`;
}).join('\n\n---\n\n');
// ВСЕГДА ищем тикет через API
const existingSystemTicket = await findSystemTicket(tickets);
if (existingSystemTicket) {
sendTicketMessage({
ticketId: existingSystemTicket,
message: errorMessage,
systemError: true,
});
} else {
// Создаем новый тикет для ошибки
createTicket({
message: errorMessage,
useToken: true,
systemError: true,
});
}
} catch (error) {
console.error('Error in sendErrorsToServer:', error);
} finally {
// Очищаем очередь ошибок
errorsQueue = [];
}
}
// Ищет существующий тикет с system: true
export async function findSystemTicket(tickets: Ticket[]) {
for (const ticket of tickets) {
console.log("[findSystemTicket] Проверяем тикет:", ticket);
if (!('messages' in ticket)) {
if (ticket.top_message && ticket.top_message.system === true) {
console.log("[findSystemTicket] Найден тикет по top_message.system:true:", ticket.id);
return ticket.id;
}
}
}
}
export function clearErrorHandlingConfig () {
clearTimeout(timeoutId);
errorsQueue = [];
}