UI: отправка UI-ошибок, персональный публичный чат, русские pending-файлы

This commit is contained in:
AidarKC
2026-05-14 14:16:03 +03:00
parent e73e103ac4
commit 56a69ab683
21 changed files with 488 additions and 153 deletions
+30 -1
View File
@@ -1,9 +1,11 @@
const MAX_CONTEXT_LEN = 2000;
const RECENT_WINDOW_MS = 5000;
const UI_ERROR_REPORTING_KEY = 'shine-ui-send-errors-to-server-v1';
let transport = null;
let transportDepth = 0;
const recentFingerprints = new Map();
let notifySent = null;
function nowTs() {
return Date.now();
@@ -79,6 +81,26 @@ export function setClientErrorTransport(fn) {
transport = typeof fn === 'function' ? fn : null;
}
export function setClientErrorSentNotifier(fn) {
notifySent = typeof fn === 'function' ? fn : null;
}
export function isClientErrorReportingEnabled() {
try {
return localStorage.getItem(UI_ERROR_REPORTING_KEY) === '1';
} catch {
return false;
}
}
export function setClientErrorReportingEnabled(enabled) {
try {
localStorage.setItem(UI_ERROR_REPORTING_KEY, enabled ? '1' : '0');
} catch {
// ignore storage errors
}
}
export async function captureClientError(details = {}) {
const payload = buildPayload(details);
if (!payload.message) return false;
@@ -88,13 +110,20 @@ export async function captureClientError(details = {}) {
console.error('[client-error]', payload.kind, payload.message, details.error || '');
if (!transport || details.skipTransport === true || transportDepth > 0) {
if (!transport || details.skipTransport === true || transportDepth > 0 || !isClientErrorReportingEnabled()) {
return false;
}
try {
transportDepth += 1;
await transport(payload);
if (notifySent) {
try {
notifySent(payload);
} catch {
// ignore notifier errors
}
}
return true;
} catch (error) {
console.warn('client error transport failed', error);