""" Error Pattern Recognition Module Matches error messages against known patterns for faster, more accurate analysis. """ import re import logging from typing import Dict, Optional, List logger = logging.getLogger(__name__) class ErrorPatternMatcher: """Recognizes common error patterns and provides quick analysis""" def __init__(self): self.patterns = self._load_patterns() def _load_patterns(self) -> List[Dict]: """Load common error patterns with their likely causes and fixes""" return [ # Null/None Reference Errors { "pattern": r"(NullReferenceException|NullPointerException|null\s+is\s+not\s+an\s+object|Cannot\s+read\s+propert(y|ies)\s+of\s+(null|undefined))", "error_type": "null_reference", "likely_cause": "Attempting to access a property or method on a null/undefined object", "suggested_fix": "Add null/undefined checks before accessing properties", "confidence": 0.9, "languages": ["csharp", "java", "javascript", "typescript"] }, # Timeout Errors { "pattern": r"(TimeoutException|timeout|timed\s+out|ETIMEDOUT|request\s+timeout)", "error_type": "timeout", "likely_cause": "Operation exceeded time limit (network, database, or API call)", "suggested_fix": "Increase timeout value, optimize query, or implement retry logic", "confidence": 0.85, "languages": ["all"] }, # Authentication Errors { "pattern": r"(Unauthorized|401|authentication\s+failed|invalid\s+credentials|access\s+denied|forbidden|403)", "error_type": "authentication", "likely_cause": "Invalid or missing authentication credentials", "suggested_fix": "Verify API keys, tokens, or user credentials are correct and not expired", "confidence": 0.9, "languages": ["all"] }, # 500 Internal Server Errors { "pattern": r"(500\s+Internal\s+Server\s+Error|InternalServerError|unhandled\s+exception)", "error_type": "server_error", "likely_cause": "Unhandled exception in server code", "suggested_fix": "Check server logs for detailed stack trace and add error handling", "confidence": 0.8, "languages": ["all"] }, # Database Errors { "pattern": r"(SQLException|database\s+error|connection\s+refused|ECONNREFUSED|deadlock)", "error_type": "database", "likely_cause": "Database connection or query error", "suggested_fix": "Verify database connection string, check query syntax, or handle connection pooling", "confidence": 0.85, "languages": ["all"] }, # File Not Found { "pattern": r"(FileNotFoundException|ENOENT|no\s+such\s+file|file\s+not\s+found)", "error_type": "file_not_found", "likely_cause": "File path is incorrect or file doesn't exist", "suggested_fix": "Verify file path is correct and file exists before accessing", "confidence": 0.9, "languages": ["all"] }, # Index Out of Bounds { "pattern": r"(IndexOutOfBoundsException|IndexError|index\s+out\s+of\s+range|array\s+index)", "error_type": "index_error", "likely_cause": "Accessing array/list index that doesn't exist", "suggested_fix": "Check array length before accessing index or use bounds checking", "confidence": 0.9, "languages": ["all"] }, # Type Errors { "pattern": r"(TypeError|type\s+mismatch|cannot\s+convert|invalid\s+cast)", "error_type": "type_error", "likely_cause": "Type mismatch or invalid type conversion", "suggested_fix": "Verify data types match expected types or add type conversion", "confidence": 0.85, "languages": ["all"] }, # Memory Errors { "pattern": r"(OutOfMemoryError|memory\s+limit|heap\s+space|stack\s+overflow)", "error_type": "memory_error", "likely_cause": "Insufficient memory or infinite recursion", "suggested_fix": "Optimize memory usage, increase heap size, or fix recursive calls", "confidence": 0.85, "languages": ["all"] }, # Network Errors { "pattern": r"(NetworkError|ENOTFOUND|DNS\s+lookup|connection\s+reset|ECONNRESET)", "error_type": "network_error", "likely_cause": "Network connectivity issue or DNS resolution failure", "suggested_fix": "Check network connection, verify URL/hostname, or implement retry logic", "confidence": 0.85, "languages": ["all"] } ] def match(self, error_message: str, stack_trace: str = "") -> Optional[Dict]: """ Match error message against known patterns Returns: Dict with pattern match info or None if no match """ combined_text = f"{error_message} {stack_trace}".lower() for pattern_info in self.patterns: if re.search(pattern_info["pattern"], combined_text, re.IGNORECASE): logger.info(f"✓ Matched error pattern: {pattern_info['error_type']} (confidence: {pattern_info['confidence']})") return { "matched": True, "error_type": pattern_info["error_type"], "likely_cause": pattern_info["likely_cause"], "suggested_fix": pattern_info["suggested_fix"], "confidence": pattern_info["confidence"], "pattern_based": True # Flag to indicate this is from pattern matching } logger.info("No error pattern matched - using full LLM analysis") return None # Singleton instance _matcher = None def get_error_pattern_matcher() -> ErrorPatternMatcher: """Get or create error pattern matcher instance""" global _matcher if _matcher is None: _matcher = ErrorPatternMatcher() return _matcher