(() => { if (typeof window === 'undefined') { return; } if (window.__tenantpilotUnhandledRejectionLoggerApplied) { return; } window.__tenantpilotUnhandledRejectionLoggerApplied = true; const recentKeys = new Map(); const cleanupRecentKeys = (nowMs) => { for (const [key, timestampMs] of recentKeys.entries()) { if (nowMs - timestampMs > 5_000) { recentKeys.delete(key); } } }; const normalizeReason = (value, depth = 0) => { if (depth > 3) { return '[max-depth-reached]'; } if (value instanceof Error) { return { type: 'Error', name: value.name, message: value.message, stack: value.stack, }; } if (value === null || value === undefined) { return value; } if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') { return value; } if (Array.isArray(value)) { return value.slice(0, 10).map((item) => normalizeReason(item, depth + 1)); } if (typeof value === 'object') { const result = {}; const allowedKeys = [ 'message', 'stack', 'name', 'type', 'status', 'body', 'json', 'errors', 'reason', 'code', ]; for (const key of allowedKeys) { if (Object.prototype.hasOwnProperty.call(value, key)) { result[key] = normalizeReason(value[key], depth + 1); } } if (Object.keys(result).length > 0) { return result; } const stringTag = Object.prototype.toString.call(value); return { type: stringTag, value: String(value), }; } return String(value); }; const toStableJson = (payload) => { try { return JSON.stringify(payload); } catch { return JSON.stringify({ source: payload.source, href: payload.href, timestamp: payload.timestamp, reason: '[unserializable]', }); } }; window.addEventListener('unhandledrejection', (event) => { const payload = { source: 'window.unhandledrejection', href: window.location.href, timestamp: new Date().toISOString(), reason: normalizeReason(event.reason), }; const payloadJson = toStableJson(payload); const nowMs = Date.now(); cleanupRecentKeys(nowMs); if (recentKeys.has(payloadJson)) { return; } recentKeys.set(payloadJson, nowMs); console.error(`TenantPilot unhandled promise rejection ${payloadJson}`); }); })();