import { EnvironmentDetector } from '../adapters/detector.js';
export interface BugAnalysis {
possibleCauses: string[];
suggestedFixes: string[];
priority: number[];
recommendedFiles: string[];
}
export class BugAnalyzer {
private detector: EnvironmentDetector;
constructor() {
this.detector = new EnvironmentDetector();
}
/**
* Analyze bug description and suggest possible causes
*/
analyzeBug(
bugDescription: string,
files?: string[],
context?: string
): BugAnalysis {
const causes: string[] = [];
const fixes: string[] = [];
const priority: number[] = [];
const recommendedFiles: string[] = [];
const lowerDesc = bugDescription.toLowerCase();
// Analyze common bug patterns
// 1. Click/interaction issues
if (lowerDesc.includes('click') || lowerDesc.includes('button') || lowerDesc.includes('没有反应')) {
causes.push('Event listener not properly attached');
fixes.push('Check if event listeners are correctly bound using addEventListener or onClick');
priority.push(1);
recommendedFiles.push('Event handlers, component files');
causes.push('CSS z-index or pointer-events blocking interaction');
fixes.push('Inspect CSS for overlapping elements with higher z-index or pointer-events: none');
priority.push(2);
recommendedFiles.push('CSS files, styled components');
causes.push('JavaScript error preventing click handler execution');
fixes.push('Check browser console for JavaScript errors before the click');
priority.push(3);
recommendedFiles.push('Browser console, error handlers');
}
// 2. Login/auth issues
if (lowerDesc.includes('login') || lowerDesc.includes('auth') || lowerDesc.includes('登录')) {
causes.push('API endpoint returning error (401, 403, 500, etc.)');
fixes.push('Add debug logging to API request/response to check status codes');
priority.push(1);
recommendedFiles.push('API calls, axios/fetch code');
causes.push('Incorrect credentials being sent');
fixes.push('Log the request payload to verify username/password are correct');
priority.push(2);
recommendedFiles.push('Login form handlers');
causes.push('Session/token not being stored properly');
fixes.push('Check localStorage, sessionStorage, or cookie handling after login');
priority.push(3);
recommendedFiles.push('Auth utilities, storage handlers');
}
// 3. Display/rendering issues
if (lowerDesc.includes('display') || lowerDesc.includes('show') || lowerDesc.includes('render') || lowerDesc.includes('显示')) {
causes.push('Data not being loaded or undefined');
fixes.push('Add debug logs to check if data exists before rendering');
priority.push(1);
recommendedFiles.push('Component files, data fetching code');
causes.push('Conditional rendering logic incorrect');
fixes.push('Log the conditions in if/else statements to verify flow');
priority.push(2);
recommendedFiles.push('Component render methods');
causes.push('CSS hiding the element');
fixes.push('Check for display: none, visibility: hidden, or opacity: 0');
priority.push(3);
recommendedFiles.push('CSS files, inline styles');
}
// 4. API issues
if (lowerDesc.includes('api') || lowerDesc.includes('request') || lowerDesc.includes('fetch') || lowerDesc.includes('ajax')) {
causes.push('Network request failing or timeout');
fixes.push('Log request URL, headers, and body; check response status');
priority.push(1);
recommendedFiles.push('API client, fetch code');
causes.push('CORS issue blocking the request');
fixes.push('Check browser console for CORS errors; verify server CORS config');
priority.push(2);
recommendedFiles.push('Server CORS middleware');
causes.push('Request payload format incorrect');
fixes.push('Log the request body to match expected API format');
priority.push(3);
recommendedFiles.push('API call sites');
}
// 5. State management issues
if (lowerDesc.includes('state') || lowerDesc.includes('update') || lowerDesc.includes('change') || lowerDesc.includes('更新')) {
causes.push('State not triggering re-render');
fixes.push('Verify state updates using proper setState or useState');
priority.push(1);
recommendedFiles.push('Component files, state management');
causes.push('State mutation instead of immutable update');
fixes.push('Log state before and after update to check if reference changed');
priority.push(2);
recommendedFiles.push('State update logic');
causes.push('Async state update timing issue');
fixes.push('Add logging to check state values after async operations');
priority.push(3);
recommendedFiles.push('Async handlers, useEffect, componentDidMount');
}
// 6. Data issues
if (lowerDesc.includes('data') || lowerDesc.includes('array') || lowerDesc.includes('object') || lowerDesc.includes('数据')) {
causes.push('Data structure mismatch between frontend and backend');
fixes.push('Log the actual data structure to compare with expected format');
priority.push(1);
recommendedFiles.push('Data transformation code');
causes.push('Undefined/null values not handled');
fixes.push('Add null checks and optional chaining; log data access');
priority.push(2);
recommendedFiles.push('Component rendering, data access code');
causes.push('Array/object being modified unexpectedly');
fixes.push('Use deep cloning and log before/after modifications');
priority.push(3);
recommendedFiles.push('Data mutation code');
}
// 7. Performance issues
if (lowerDesc.includes('slow') || lowerDesc.includes('lag') || lowerDesc.includes('卡') || lowerDesc.includes('慢')) {
causes.push('Inefficient re-renders or computations');
fixes.push('Add performance logging and check React DevTools Profiler');
priority.push(1);
recommendedFiles.push('Component files, expensive functions');
causes.push('Large data not being paginated or virtualized');
fixes.push('Log data size; implement pagination or windowing');
priority.push(2);
recommendedFiles.push('List rendering code');
causes.push('Memory leak from unsubscribed effects');
fixes.push('Check useEffect cleanup functions and event listener removal');
priority.push(3);
recommendedFiles.push('useEffect, componentDidMount, componentWillUnmount');
}
// 8. Form issues
if (lowerDesc.includes('form') || lowerDesc.includes('input') || lowerDesc.includes('submit') || lowerDesc.includes('validation')) {
causes.push('Form validation preventing submission');
fixes.push('Log validation errors and form state');
priority.push(1);
recommendedFiles.push('Form validation code');
causes.push('Form data not being captured correctly');
fixes.push('Log form values on change and submit');
priority.push(2);
recommendedFiles.push('Form input handlers');
causes.push('Submit handler not being called');
fixes.push('Add debug log in submit handler to verify execution');
priority.push(3);
recommendedFiles.push('Form onSubmit handlers');
}
// Default analysis if no specific pattern detected
if (causes.length === 0) {
causes.push('Unclear issue - need more context');
fixes.push('Add debug logs to track program flow and variable values');
priority.push(1);
recommendedFiles.push('All relevant files');
}
return {
possibleCauses: causes,
suggestedFixes: fixes,
priority,
recommendedFiles
};
}
/**
* Analyze debug logs to find patterns or anomalies
*/
analyzeDebugLogs(logs: string[]): {
patterns: string[];
anomalies: string[];
summary: string;
} {
const patterns: string[] = [];
const anomalies: string[] = [];
// Analyze log patterns
const errorLogs = logs.filter(log =>
log.toLowerCase().includes('error') ||
log.toLowerCase().includes('fail') ||
log.toLowerCase().includes('exception')
);
if (errorLogs.length > 0) {
patterns.push(`Found ${errorLogs.length} error(s) in logs`);
anomalies.push(...errorLogs.slice(0, 5)); // First 5 errors
}
// Check for HTTP status codes
const statusCodes = logs.flatMap(log => {
const matches = log.match(/\b[45]\d{2}\b/g);
return matches || [];
});
if (statusCodes.length > 0) {
const uniqueCodes = [...new Set(statusCodes)];
patterns.push(`HTTP errors: ${uniqueCodes.join(', ')}`);
}
// Check for undefined/null values
const nullLogs = logs.filter(log =>
log.toLowerCase().includes('undefined') ||
log.toLowerCase().includes('null')
);
if (nullLogs.length > 0) {
patterns.push(`Found ${nullLogs.length} instances of undefined/null values`);
}
// Generate summary
let summary = `Analyzed ${logs.length} log entries`;
if (errorLogs.length > 0) {
summary += `. Found ${errorLogs.length} error(s)`;
}
if (statusCodes.length > 0) {
summary += `. Detected HTTP errors: ${[...new Set(statusCodes)].join(', ')}`;
}
return {
patterns,
anomalies,
summary
};
}
/**
* Suggest next debugging steps based on current state
*/
suggestNextSteps(
bugDescription: string,
logs: string[],
attemptNumber: number
): string[] {
const steps: string[] = [];
if (attemptNumber === 1) {
steps.push('Add debug logs to track the execution flow');
steps.push('Log the values of key variables at different points');
steps.push('Check browser console or server logs for errors');
} else if (logs.length === 0) {
steps.push('No logs received - verify debug code is being executed');
steps.push('Check if the code path is actually being reached');
steps.push('Add more debug logs in earlier code sections');
} else {
const hasErrors = logs.some(log =>
log.toLowerCase().includes('error') ||
log.toLowerCase().includes('fail')
);
if (hasErrors) {
steps.push('Investigate the errors found in logs');
steps.push('Add debug logs before and after the error location');
} else {
steps.push('Logs show no errors - issue might be in logic flow');
steps.push('Add conditional debug logs to track branch execution');
steps.push('Verify assumptions about data and state');
}
}
return steps;
}
}