|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ErrorHelper {
|
|
|
constructor() {
|
|
|
this.errorHistory = [];
|
|
|
this.autoFixEnabled = true;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
analyzeError(error, context = {}) {
|
|
|
const analysis = {
|
|
|
error: error.message || String(error),
|
|
|
type: this.detectErrorType(error),
|
|
|
suggestions: [],
|
|
|
autoFix: null,
|
|
|
severity: 'medium'
|
|
|
};
|
|
|
|
|
|
|
|
|
if (error.message?.includes('500') || error.message?.includes('Internal Server Error')) {
|
|
|
analysis.suggestions.push('Server error - check backend logs');
|
|
|
analysis.suggestions.push('Try refreshing the page');
|
|
|
analysis.severity = 'high';
|
|
|
}
|
|
|
|
|
|
if (error.message?.includes('404') || error.message?.includes('Not Found')) {
|
|
|
analysis.suggestions.push('Endpoint not found - check API URL');
|
|
|
analysis.suggestions.push('Verify backend is running');
|
|
|
analysis.severity = 'medium';
|
|
|
}
|
|
|
|
|
|
if (error.message?.includes('CORS') || error.message?.includes('cross-origin')) {
|
|
|
analysis.suggestions.push('CORS error - check backend CORS settings');
|
|
|
analysis.severity = 'high';
|
|
|
}
|
|
|
|
|
|
if (error.message?.includes('WebSocket')) {
|
|
|
analysis.suggestions.push('WebSocket connection failed');
|
|
|
analysis.suggestions.push('Check if WebSocket endpoint is available');
|
|
|
analysis.autoFix = () => this.reconnectWebSocket();
|
|
|
analysis.severity = 'medium';
|
|
|
}
|
|
|
|
|
|
if (error.message?.includes('symbol') || error.message?.includes('BTC')) {
|
|
|
analysis.suggestions.push('Invalid symbol - try BTC, ETH, SOL, etc.');
|
|
|
analysis.autoFix = () => this.fixSymbol(context.symbol);
|
|
|
analysis.severity = 'low';
|
|
|
}
|
|
|
|
|
|
this.errorHistory.push({
|
|
|
...analysis,
|
|
|
timestamp: new Date().toISOString(),
|
|
|
context
|
|
|
});
|
|
|
|
|
|
return analysis;
|
|
|
}
|
|
|
|
|
|
detectErrorType(error) {
|
|
|
const msg = String(error.message || error).toLowerCase();
|
|
|
if (msg.includes('network') || msg.includes('fetch')) return 'network';
|
|
|
if (msg.includes('500') || msg.includes('server')) return 'server';
|
|
|
if (msg.includes('404') || msg.includes('not found')) return 'not_found';
|
|
|
if (msg.includes('cors')) return 'cors';
|
|
|
if (msg.includes('websocket')) return 'websocket';
|
|
|
if (msg.includes('timeout')) return 'timeout';
|
|
|
return 'unknown';
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async autoFix(error, context = {}) {
|
|
|
if (!this.autoFixEnabled) return false;
|
|
|
|
|
|
const analysis = this.analyzeError(error, context);
|
|
|
|
|
|
if (analysis.autoFix) {
|
|
|
try {
|
|
|
await analysis.autoFix();
|
|
|
return true;
|
|
|
} catch (e) {
|
|
|
console.error('Auto-fix failed:', e);
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
if (analysis.type === 'network') {
|
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
fixSymbol(symbol) {
|
|
|
if (!symbol) return 'BTC';
|
|
|
|
|
|
return symbol.trim().toUpperCase().replace(/\s+/g, '');
|
|
|
}
|
|
|
|
|
|
async reconnectWebSocket() {
|
|
|
|
|
|
if (typeof window !== 'undefined' && window.wsClient) {
|
|
|
window.wsClient.disconnect();
|
|
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
|
window.wsClient.connect();
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
getStats() {
|
|
|
const types = {};
|
|
|
this.errorHistory.forEach(err => {
|
|
|
types[err.type] = (types[err.type] || 0) + 1;
|
|
|
});
|
|
|
return {
|
|
|
total: this.errorHistory.length,
|
|
|
byType: types,
|
|
|
recent: this.errorHistory.slice(-10)
|
|
|
};
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
clear() {
|
|
|
this.errorHistory = [];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
const errorHelper = new ErrorHelper();
|
|
|
|
|
|
|
|
|
window.addEventListener('error', (event) => {
|
|
|
errorHelper.analyzeError(event.error || event.message, {
|
|
|
filename: event.filename,
|
|
|
lineno: event.lineno,
|
|
|
colno: event.colno
|
|
|
});
|
|
|
});
|
|
|
|
|
|
window.addEventListener('unhandledrejection', (event) => {
|
|
|
errorHelper.analyzeError(event.reason, {
|
|
|
type: 'unhandled_promise_rejection'
|
|
|
});
|
|
|
});
|
|
|
|
|
|
export default errorHelper;
|
|
|
|
|
|
|