'''Pattern library for error detection.''' import re from dataclasses import dataclass, field from typing import Optional @dataclass class ErrorPattern: '''Represents an error detection pattern.''' name: str pattern: str severity: str = "error" description: str = "" suggestion: str = "" group: str = "general" enabled: bool = True def __post_init__(self): try: self._regex = re.compile(self.pattern, re.IGNORECASE) except re.error: self._regex = re.compile(re.escape(self.pattern), re.IGNORECASE) def match(self, text: str) -> Optional[re.Match]: '''Match pattern against text.''' if not self.enabled: return None return self._regex.search(text) @dataclass class PatternGroup: '''Group of related patterns.''' name: str patterns: list[ErrorPattern] = field(default_factory=list) class PatternLibrary: '''Library of error detection patterns.''' def __init__(self): self._patterns: list[ErrorPattern] = [] self._groups: dict[str, PatternGroup] = {} self._load_default_patterns() def _load_default_patterns(self) -> None: '''Load default error patterns.''' self._patterns = [ ErrorPattern( name="Python Exception", pattern=r"(Traceback|Exception|Error|Traceback \(most recent call last\))", severity="error", description="Python exception detected", suggestion="Check the exception type and stack trace to identify the root cause", group="exceptions", ), ErrorPattern( name="Java Stack Trace", pattern=r"(java\.lang\.|Exception in thread|at \w+\.\w+\.\w+)", severity="error", description="Java exception/stack trace detected", suggestion="Review the Java stack trace for the exception cause", group="exceptions", ), ErrorPattern( name="Connection Refused", pattern=r"Connection refused|ECONNREFUSED", severity="error", description="Connection was refused", suggestion="Check if the service is running and the port is correct", group="network", ), ErrorPattern( name="Connection Timeout", pattern=r"Connection timed out|ETIMEDOUT|timeout|Timed out", severity="error", description="Connection timed out", suggestion="Check network connectivity and server responsiveness", group="network", ), ErrorPattern( name="Database Error", pattern=r"(mysql|postgres|sqlite|mongodb|redis).*(error|exception|failed)", severity="error", description="Database error detected", suggestion="Check database connectivity and query syntax", group="database", ), ErrorPattern( name="SQL Error", pattern=r"(syntax error|undefined column|duplicate key|constraint violation)", severity="error", description="SQL error detected", suggestion="Review the SQL query for syntax errors", group="database", ), ErrorPattern( name="HTTP 5xx Error", pattern=r"HTTP Error (5\d{2})|Status: (5\d{2})", severity="error", description="Server-side HTTP error", suggestion="Check server logs for the root cause", group="http", ), ErrorPattern( name="HTTP 4xx Error", pattern=r"HTTP Error (4\d{2})|Status: (4\d{2})", severity="warning", description="Client-side HTTP error", suggestion="Check request URL and parameters", group="http", ), ErrorPattern( name="Null Pointer", pattern=r"(NullPointerException|null reference|NoneType|is None)", severity="error", description="Null pointer/null reference error", suggestion="Add null checks before accessing objects", group="exceptions", ), ErrorPattern( name="Index Error", pattern=r"(IndexError|array index|list index|index out of range)", severity="error", description="Index out of bounds error", suggestion="Check array/list bounds before access", group="exceptions", ), ErrorPattern( name="Key Error", pattern=r"(KeyError|missing key|dict key|Key not found)", severity="error", description="Key not found in dictionary/map", suggestion="Add key existence checks or use .get() method", group="exceptions", ), ErrorPattern( name="Permission Denied", pattern=r"(Permission denied|EACCES|Access denied)", severity="error", description="Permission denied error", suggestion="Check file/directory permissions", group="system", ), ErrorPattern( name="Disk Full", pattern=r"(No space left|ENOSPC|Disk full|Out of space)", severity="critical", description="Disk space exhausted", suggestion="Free up disk space or increase storage", group="system", ), ErrorPattern( name="Memory Error", pattern=r"(MemoryError|Out of memory|Killed|OOM)", severity="critical", description="Out of memory error", suggestion="Increase memory or optimize memory usage", group="system", ), ErrorPattern( name="Segmentation Fault", pattern=r"(Segmentation fault|SegFault|SIGSEGV|core dumped)", severity="critical", description="Segmentation fault", suggestion="Check for null pointer dereferences or buffer overflows", group="system", ), ErrorPattern( name="Panic", pattern=r"(panic|PANIC|fatal error)", severity="critical", description="Application panic", suggestion="Review panic message and stack trace", group="system", ), ErrorPattern( name="Deprecated", pattern=r"(deprecated|DeprecationWarning|deprecated method)", severity="info", description="Deprecated feature usage", suggestion="Update to the recommended replacement", group="code_quality", ), ErrorPattern( name="Warning", pattern=r"(warning|Warning|WARN)", severity="warning", description="General warning", suggestion="Review warning message for potential issues", group="general", ), ErrorPattern( name="Debug", pattern=r"(debug|DEBUG|Trace)", severity="debug", description="Debug message", suggestion="Ignore unless debugging", group="general", ), ErrorPattern( name="Authentication Failed", pattern=r"(Authentication failed|Login failed|Invalid credentials|401 Unauthorized)", severity="error", description="Authentication failure", suggestion="Verify username/password or API key", group="security", ), ErrorPattern( name="SSL/TLS Error", pattern=r"(SSL|Certificate|TLS|handshake|ssl error)", severity="error", description="SSL/TLS error", suggestion="Check certificate validity and configuration", group="security", ), ] self._groups = { "exceptions": PatternGroup( name="Exceptions", patterns=[p for p in self._patterns if p.group == "exceptions"] ), "network": PatternGroup( name="Network", patterns=[p for p in self._patterns if p.group == "network"] ), "database": PatternGroup( name="Database", patterns=[p for p in self._patterns if p.group == "database"] ), "http": PatternGroup( name="HTTP", patterns=[p for p in self._patterns if p.group == "http"] ), "system": PatternGroup( name="System", patterns=[p for p in self._patterns if p.group == "system"] ), "security": PatternGroup( name="Security", patterns=[p for p in self._patterns if p.group == "security"] ), "code_quality": PatternGroup( name="Code Quality", patterns=[p for p in self._patterns if p.group == "code_quality"], ), "general": PatternGroup( name="General", patterns=[p for p in self._patterns if p.group == "general"] ), } def detect(self, text: str) -> list[tuple[ErrorPattern, re.Match]]: '''Detect all patterns matching the text.''' matches = [] for pattern in self._patterns: if pattern.enabled: match = pattern.match(text) if match: matches.append((pattern, match)) return matches def find_match(self, text: str) -> Optional[tuple[ErrorPattern, re.Match]]: '''Find the first matching pattern.''' for pattern in self._patterns: if pattern.enabled: match = pattern.match(text) if match: return (pattern, match) return None def get_patterns_by_severity(self, severity: str) -> list[ErrorPattern]: '''Get patterns by severity level.''' return [p for p in self._patterns if p.severity == severity] def get_patterns_by_group(self, group: str) -> list[ErrorPattern]: '''Get patterns by group.''' return [p for p in self._patterns if p.group == group] def add_pattern(self, pattern: ErrorPattern) -> None: '''Add a custom pattern.''' self._patterns.append(pattern) def remove_pattern(self, name: str) -> bool: '''Remove a pattern by name.''' for i, p in enumerate(self._patterns): if p.name == name: self._patterns.pop(i) return True return False def disable_pattern(self, name: str) -> bool: '''Disable a pattern by name.''' for p in self._patterns: if p.name == name: p.enabled = False return True return False def enable_pattern(self, name: str) -> bool: '''Enable a pattern by name.''' for p in self._patterns: if p.name == name: p.enabled = True return True return False def list_patterns(self) -> list[ErrorPattern]: '''List all patterns.''' return self._patterns.copy() def list_groups(self) -> dict[str, list[ErrorPattern]]: '''List patterns by group.''' return {name: group.patterns.copy() for name, group in self._groups.items()}