Files
Agent-n8n/web_frontend/web_result/js/error-handler.js

279 lines
9.6 KiB
JavaScript
Raw Normal View History

// 错误处理和兼容性脚本
(function() {
'use strict';
// 全局错误处理
window.addEventListener('error', function(event) {
console.error('Global error:', {
message: event.message,
filename: event.filename,
lineno: event.lineno,
colno: event.colno,
error: event.error
});
// 发送错误到控制台(便于调试)
if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') {
console.group('Error Details:');
console.log('Message:', event.message);
console.log('File:', event.filename);
console.log('Line:', event.lineno + ':' + event.colno);
if (event.error && event.error.stack) {
console.log('Stack:', event.error.stack);
}
console.groupEnd();
}
return true; // 阻止默认错误处理
});
// Promise 错误处理
window.addEventListener('unhandledrejection', function(event) {
console.error('Unhandled promise rejection:', event.reason);
if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') {
console.group('Promise Rejection:');
console.log('Reason:', event.reason);
if (event.reason && event.reason.stack) {
console.log('Stack:', event.reason.stack);
}
console.groupEnd();
}
event.preventDefault(); // 阻止默认处理
});
// DOM 查询安全包装
function safeQuerySelector(selector) {
try {
return document.querySelector(selector);
} catch (e) {
console.warn('Invalid selector:', selector, e);
return null;
}
}
function safeQuerySelectorAll(selector) {
try {
return document.querySelectorAll(selector);
} catch (e) {
console.warn('Invalid selector:', selector, e);
return [];
}
}
// 安全的getElementById
function safeGetElementById(id) {
try {
return document.getElementById(id);
} catch (e) {
console.warn('Invalid element ID:', id, e);
return null;
}
}
// 修复常见的兼容性问题
function fixCompatibilityIssues() {
// 修复classList不支持的情况简化版本以避免Illegal invocation
try {
// 安全检测classList支持
var testElement = document.createElement('div');
if (!testElement.classList) {
// 简单的classList polyfill
window.ClassListPolyfill = {
addClass: function(element, className) {
if (element && className) {
var classes = element.className ? element.className.split(' ') : [];
if (classes.indexOf(className) === -1) {
classes.push(className);
element.className = classes.join(' ').trim();
}
}
},
removeClass: function(element, className) {
if (element && className) {
var classes = element.className ? element.className.split(' ') : [];
var index = classes.indexOf(className);
if (index !== -1) {
classes.splice(index, 1);
element.className = classes.join(' ').trim();
}
}
},
hasClass: function(element, className) {
if (!element || !className) return false;
var classes = element.className ? element.className.split(' ') : [];
return classes.indexOf(className) !== -1;
}
};
}
} catch (e) {
// 如果检测失败,忽略错误
console.warn('classList detection failed:', e);
}
// 修复addEventListener不支持的情况
if (!Element.prototype.addEventListener && Element.prototype.attachEvent) {
Element.prototype.addEventListener = function(event, listener) {
this.attachEvent('on' + event, listener);
};
Element.prototype.removeEventListener = function(event, listener) {
this.detachEvent('on' + event, listener);
};
}
// 修复Array.from不支持的情况
if (!Array.from) {
Array.from = function(arrayLike) {
var result = [];
for (var i = 0; i < arrayLike.length; i++) {
result.push(arrayLike[i]);
}
return result;
};
}
// 修复forEach不支持的情况
if (!NodeList.prototype.forEach) {
NodeList.prototype.forEach = function(callback, thisArg) {
for (var i = 0; i < this.length; i++) {
callback.call(thisArg, this[i], i, this);
}
};
}
}
// 检测浏览器支持情况
function detectBrowserSupport() {
const features = {
es6: {
arrow: false,
const: false,
let: false,
template: false,
destructuring: false
},
dom: {
classList: (function() {
try {
var testElement = document.createElement('div');
return !!testElement.classList;
} catch (e) {
return false;
}
})(),
querySelector: !!document.querySelector,
addEventListener: !!window.addEventListener
},
css: {
grid: typeof CSS !== 'undefined' && CSS.supports && CSS.supports('display', 'grid'),
flexbox: typeof CSS !== 'undefined' && CSS.supports && CSS.supports('display', 'flex'),
transform: typeof CSS !== 'undefined' && CSS.supports && CSS.supports('transform', 'translateX(0)')
}
};
// 测试ES6功能
try {
eval('const x = 1');
features.es6.const = true;
} catch (e) {}
try {
eval('let x = 1');
features.es6.let = true;
} catch (e) {}
try {
eval('`template`');
features.es6.template = true;
} catch (e) {}
try {
eval('() => {}');
features.es6.arrow = true;
} catch (e) {}
if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') {
console.group('Browser Support:');
console.table(features);
console.groupEnd();
}
return features;
}
// 修复具体的错误
function fixSpecificErrors() {
// 确保所有必要的元素存在
const requiredElements = [
'navbar',
'mobile-menu-button',
'mobile-menu',
'mobile-menu-overlay',
'close-menu'
];
setTimeout(function() {
requiredElements.forEach(function(id) {
const element = document.getElementById(id);
if (!element) {
console.warn('Missing required element:', id);
// 尝试创建缺失的元素(某些情况下)
if (id === 'mobile-menu-overlay' && !document.getElementById(id)) {
const overlay = document.createElement('div');
overlay.id = id;
overlay.className = 'mobile-menu-overlay hidden';
document.body.appendChild(overlay);
console.log('Created missing overlay element');
}
}
});
}, 1000);
}
// 安全的脚本加载
function safeLoadScript(src, callback) {
const script = document.createElement('script');
script.src = src;
script.onload = function() {
if (callback) callback();
};
script.onerror = function() {
console.error('Failed to load script:', src);
};
document.head.appendChild(script);
}
// 初始化错误处理
function init() {
// 修复兼容性问题
fixCompatibilityIssues();
// 检测浏览器支持
detectBrowserSupport();
// 修复具体错误
fixSpecificErrors();
// 为调试添加全局工具
if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') {
window.debugTools = {
safeQuerySelector: safeQuerySelector,
safeQuerySelectorAll: safeQuerySelectorAll,
safeGetElementById: safeGetElementById,
fixCompatibilityIssues: fixCompatibilityIssues,
detectBrowserSupport: detectBrowserSupport
};
}
console.log('Error handler initialized');
}
// 在DOM加载后初始化
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();