Add analyzers (patterns, severity, analyzer)
Some checks failed
CI / test (3.11) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled
CI / test (3.10) (push) Has been cancelled
CI / test (3.9) (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / build (push) Has been cancelled

This commit is contained in:
2026-02-02 10:08:35 +00:00
parent 7bbe910333
commit c0758d1f2b

View File

@@ -1,222 +1,311 @@
from dataclasses import dataclass """Pattern library for error detection."""
import re
from dataclasses import dataclass, field
from typing import Optional from typing import Optional
@dataclass @dataclass
class ErrorPattern: class ErrorPattern:
"""Error pattern definition.""" """Represents an error detection pattern."""
name: str name: str
pattern: str pattern: str
severity: str severity: str = "error"
description: str description: str = ""
suggestion: str = ""
group: str = "general" 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: class PatternLibrary:
"""Library of error detection patterns.""" """Library of error detection patterns."""
def __init__(self): def __init__(self):
self._patterns = self._load_patterns() self._patterns: list[ErrorPattern] = []
self._groups: dict[str, PatternGroup] = {}
self._load_default_patterns()
def _load_patterns(self) -> list[ErrorPattern]: def _load_default_patterns(self) -> None:
"""Load all error patterns.""" """Load default error patterns."""
return [ self._patterns = [
ErrorPattern( ErrorPattern(
name="Python Exception", name="Python Exception",
pattern=r"(?:Traceback|Exception|Error|Error:)", pattern=r"(Traceback|Exception|Error|Traceback \(most recent call last\))",
severity="error", severity="error",
description="Python exception or error", description="Python exception detected",
suggestion="Check the exception type and stack trace to identify the root cause",
group="exceptions", group="exceptions",
), ),
ErrorPattern( ErrorPattern(
name="Python Traceback", name="Java Stack Trace",
pattern=r"Traceback \(most recent call last\)", pattern=r"(java\.lang\.|Exception in thread|at \w+\.\w+\.\w+)",
severity="error", severity="error",
description="Python traceback", description="Java exception/stack trace detected",
group="exceptions", suggestion="Review the Java stack trace for the exception cause",
),
ErrorPattern(
name="Java Exception",
pattern=r"(?:Exception|Error|NullPointerException|IllegalArgumentException)",
severity="error",
description="Java exception",
group="exceptions",
),
ErrorPattern(
name="Stack Trace",
pattern=r"(?:at [a-zA-Z0-9_.]+\([a-zA-Z0-9_.]+\.java:[0-9]+\)|\(Unknown Source\))",
severity="error",
description="Stack trace element",
group="exceptions", group="exceptions",
), ),
ErrorPattern( ErrorPattern(
name="Connection Refused", name="Connection Refused",
pattern=r"(?:Connection refused|ECONNREFUSED)", pattern=r"Connection refused|ECONNREFUSED",
severity="error", severity="error",
description="Connection refused by remote host", description="Connection was refused",
suggestion="Check if the service is running and the port is correct",
group="network", group="network",
), ),
ErrorPattern( ErrorPattern(
name="Connection Timeout", name="Connection Timeout",
pattern=r"(?:Connection timed out|ETIMEDOUT|Timeout)", pattern=r"Connection timed out|ETIMEDOUT|timeout|Timed out",
severity="error", severity="error",
description="Connection timeout", description="Connection timed out",
suggestion="Check network connectivity and server responsiveness",
group="network", group="network",
), ),
ErrorPattern( ErrorPattern(
name="DNS Error", name="Database Error",
pattern=r"(?:DNS|NXDOMAIN|host not found)", pattern=r"(mysql|postgres|sqlite|mongodb|redis).*(error|exception|failed)",
severity="error", severity="error",
description="DNS resolution error", description="Database error detected",
group="network", 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( ErrorPattern(
name="HTTP 5xx Error", name="HTTP 5xx Error",
pattern=r"(?:HTTP/[0-9\.]+\s+[5][0-9]{2}|Status: 5\d{2})", pattern=r"HTTP Error (5\d{2})|Status: (5\d{2})",
severity="error", severity="error",
description="HTTP server error (5xx)", description="Server-side HTTP error",
suggestion="Check server logs for the root cause",
group="http", group="http",
), ),
ErrorPattern( ErrorPattern(
name="HTTP 4xx Error", name="HTTP 4xx Error",
pattern=r"(?:HTTP/[0-9\.]+\s+[4][0-9]{2}|Status: 4\d{2})", pattern=r"HTTP Error (4\d{2})|Status: (4\d{2})",
severity="warning", severity="warning",
description="HTTP client error (4xx)", description="Client-side HTTP error",
suggestion="Check request URL and parameters",
group="http", group="http",
), ),
ErrorPattern( ErrorPattern(
name="Database Connection", name="Null Pointer",
pattern=r"(?:Cannot connect to database|MongoDB|SQL|ConnectionString|pymongo)", pattern=r"(NullPointerException|null reference|NoneType|is None)",
severity="error", severity="error",
description="Database connection issue", description="Null pointer/null reference error",
group="database", suggestion="Add null checks before accessing objects",
group="exceptions",
), ),
ErrorPattern( ErrorPattern(
name="Authentication Failed", name="Index Error",
pattern=r"(?:Authentication failed|Auth failed|Invalid credentials|Permission denied)", pattern=r"(IndexError|array index|list index|index out of range)",
severity="error", severity="error",
description="Authentication failure", description="Index out of bounds error",
group="security", suggestion="Check array/list bounds before access",
group="exceptions",
), ),
ErrorPattern( ErrorPattern(
name="SSL/TLS Error", name="Key Error",
pattern=r"(?:SSL|TLS|handshake|certificate|HTTPSConnection)", pattern=r"(KeyError|missing key|dict key|Key not found)",
severity="error", severity="error",
description="SSL/TLS error", description="Key not found in dictionary/map",
group="security", 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( ErrorPattern(
name="Disk Full", name="Disk Full",
pattern=r"(?:No space left on device|Disk full|ENOSPC)", pattern=r"(No space left|ENOSPC|Disk full|Out of space)",
severity="critical", severity="critical",
description="Disk space exhausted", description="Disk space exhausted",
suggestion="Free up disk space or increase storage",
group="system", group="system",
), ),
ErrorPattern( ErrorPattern(
name="Memory Error", name="Memory Error",
pattern=r"(?:Out of memory|Killed|OOM|MemoryError)", pattern=r"(MemoryError|Out of memory|Killed|OOM)",
severity="critical", severity="critical",
description="Memory exhaustion", description="Out of memory error",
suggestion="Increase memory or optimize memory usage",
group="system", group="system",
), ),
ErrorPattern( ErrorPattern(
name="Segmentation Fault", name="Segmentation Fault",
pattern=r"(?:Segmentation fault|SegFault|SIGSEGV)", pattern=r"(Segmentation fault|SegFault|SIGSEGV|core dumped)",
severity="critical", severity="critical",
description="Segmentation fault", description="Segmentation fault",
suggestion="Check for null pointer dereferences or buffer overflows",
group="system", group="system",
), ),
ErrorPattern( ErrorPattern(
name="Process Crashed", name="Panic",
pattern=r"(?:Process.*exited|Crashed|exit code|signaled)", pattern=r"(panic|PANIC|fatal error)",
severity="error", severity="critical",
description="Process crash", description="Application panic",
suggestion="Review panic message and stack trace",
group="system", group="system",
), ),
ErrorPattern( ErrorPattern(
name="Deprecation Warning", name="Deprecated",
pattern=r"(?:DeprecationWarning|Deprecation|PendingDeprecationWarning)", 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", severity="debug",
description="Deprecation warning", description="Debug message",
group="code", suggestion="Ignore unless debugging",
group="general",
), ),
ErrorPattern( ErrorPattern(
name="Import Error", name="Authentication Failed",
pattern=r"(?:ImportError|ModuleNotFoundError|Cannot import|No module named)", pattern=r"(Authentication failed|Login failed|Invalid credentials|401 Unauthorized)",
severity="error", severity="error",
description="Import error", description="Authentication failure",
group="code", suggestion="Verify username/password or API key",
group="security",
), ),
ErrorPattern( ErrorPattern(
name="Key Error", name="SSL/TLS Error",
pattern=r"(?:KeyError|AttributeError|NoneType is not)", pattern=r"(SSL|Certificate|TLS|handshake|ssl error)",
severity="error", severity="error",
description="Key/Attribute error", description="SSL/TLS error",
group="code", suggestion="Check certificate validity and configuration",
), group="security",
ErrorPattern(
name="Syntax Error",
pattern=r"(?:SyntaxError|Parse error|invalid syntax)",
severity="error",
description="Syntax error",
group="code",
),
ErrorPattern(
name="File Not Found",
pattern=r"(?:FileNotFoundError|No such file or directory)",
severity="error",
description="File not found",
group="system",
),
ErrorPattern(
name="Permission Denied",
pattern=r"(?:Permission denied|EACCES|EPERM)",
severity="error",
description="Permission denied",
group="system",
),
ErrorPattern(
name="Assertion Failed",
pattern=r"(?:AssertionError|Assertion failed)",
severity="error",
description="Assertion failed",
group="code",
),
ErrorPattern(
name="Value Error",
pattern=r"(?:ValueError|Invalid value)",
severity="error",
description="Value error",
group="code",
),
ErrorPattern(
name="Container Error",
pattern=r"(?:IndexError|TypeError|list index out of range)",
severity="error",
description="Container error",
group="code",
), ),
] ]
def get_patterns_for_content(self, content: str) -> list[ErrorPattern]: self._groups = {
"""Get matching patterns for content.""" "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 = [] matches = []
for pattern in self._patterns: for pattern in self._patterns:
if re.search(pattern.pattern, content, re.IGNORECASE): if pattern.enabled:
matches.append(pattern) match = pattern.match(text)
if match:
matches.append((pattern, match))
return matches return matches
def get_all_patterns(self) -> dict[str, list[dict]]: def find_match(self, text: str) -> Optional[tuple[ErrorPattern, re.Match]]:
"""Get all patterns grouped by category.""" """Find the first matching pattern."""
groups = {}
for pattern in self._patterns: for pattern in self._patterns:
if pattern.group not in groups: if pattern.enabled:
groups[pattern.group] = [] match = pattern.match(text)
groups[pattern.group].append({ if match:
"name": pattern.name, return (pattern, match)
"pattern": pattern.pattern, return None
"severity": pattern.severity,
"description": pattern.description, def get_patterns_by_severity(self, severity: str) -> list[ErrorPattern]:
}) """Get patterns by severity level."""
return groups 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()}