|
|
class ErrorLogger { |
|
|
constructor() { |
|
|
this.logKey = 'app_error_log'; |
|
|
this.maxLogs = 100; |
|
|
this.enabled = true; |
|
|
} |
|
|
|
|
|
init() { |
|
|
|
|
|
this.cleanupOldLogs(); |
|
|
|
|
|
|
|
|
window.addEventListener('error', (event) => { |
|
|
this.logError({ |
|
|
type: 'global_error', |
|
|
message: event.message, |
|
|
filename: event.filename, |
|
|
lineno: event.lineno, |
|
|
colno: event.colno, |
|
|
error: event.error?.toString(), |
|
|
timestamp: new Date().toISOString() |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
window.addEventListener('unhandledrejection', (event) => { |
|
|
this.logError({ |
|
|
type: 'unhandled_rejection', |
|
|
reason: event.reason?.toString(), |
|
|
timestamp: new Date().toISOString() |
|
|
}); |
|
|
}); |
|
|
|
|
|
console.log('✅ Error logger initialized'); |
|
|
} |
|
|
|
|
|
logError(errorData) { |
|
|
if (!this.enabled) return; |
|
|
|
|
|
try { |
|
|
const logs = this.getLogs(); |
|
|
logs.push({ |
|
|
...errorData, |
|
|
id: this.generateId(), |
|
|
userAgent: navigator.userAgent, |
|
|
url: window.location.href |
|
|
}); |
|
|
|
|
|
|
|
|
if (logs.length > this.maxLogs) { |
|
|
logs.splice(0, logs.length - this.maxLogs); |
|
|
} |
|
|
|
|
|
localStorage.setItem(this.logKey, JSON.stringify(logs)); |
|
|
|
|
|
|
|
|
console.error('🔴 Error logged:', errorData); |
|
|
} catch (error) { |
|
|
console.error('Failed to log error:', error); |
|
|
} |
|
|
} |
|
|
|
|
|
getLogs() { |
|
|
try { |
|
|
const logs = localStorage.getItem(this.logKey); |
|
|
return logs ? JSON.parse(logs) : []; |
|
|
} catch (error) { |
|
|
console.error('Failed to get logs:', error); |
|
|
return []; |
|
|
} |
|
|
} |
|
|
|
|
|
clearLogs() { |
|
|
try { |
|
|
localStorage.removeItem(this.logKey); |
|
|
console.log('✅ Error logs cleared'); |
|
|
} catch (error) { |
|
|
console.error('Failed to clear logs:', error); |
|
|
} |
|
|
} |
|
|
|
|
|
exportLogs() { |
|
|
const logs = this.getLogs(); |
|
|
const dataStr = JSON.stringify(logs, null, 2); |
|
|
const dataBlob = new Blob([dataStr], { type: 'application/json' }); |
|
|
|
|
|
const url = URL.createObjectURL(dataBlob); |
|
|
const link = document.createElement('a'); |
|
|
link.href = url; |
|
|
link.download = `error_logs_${new Date().toISOString().split('T')[0]}.json`; |
|
|
link.click(); |
|
|
|
|
|
URL.revokeObjectURL(url); |
|
|
} |
|
|
|
|
|
cleanupOldLogs() { |
|
|
const logs = this.getLogs(); |
|
|
const oneWeekAgo = new Date(); |
|
|
oneWeekAgo.setDate(oneWeekAgo.getDate() - 7); |
|
|
|
|
|
const filteredLogs = logs.filter(log => |
|
|
new Date(log.timestamp) > oneWeekAgo |
|
|
); |
|
|
|
|
|
if (filteredLogs.length !== logs.length) { |
|
|
localStorage.setItem(this.logKey, JSON.stringify(filteredLogs)); |
|
|
} |
|
|
} |
|
|
|
|
|
generateId() { |
|
|
return Date.now().toString(36) + Math.random().toString(36).substr(2); |
|
|
} |
|
|
|
|
|
enable() { |
|
|
this.enabled = true; |
|
|
} |
|
|
|
|
|
disable() { |
|
|
this.enabled = false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const errorLogger = new ErrorLogger(); |
|
|
|
|
|
|
|
|
window.errorLogger = errorLogger; |
|
|
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', () => { |
|
|
errorLogger.init(); |
|
|
}); |