kailash 0.8.4__py3-none-any.whl → 0.8.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kailash/__init__.py +5 -11
- kailash/channels/__init__.py +2 -1
- kailash/channels/mcp_channel.py +23 -4
- kailash/cli/__init__.py +11 -1
- kailash/cli/validate_imports.py +202 -0
- kailash/cli/validation_audit.py +570 -0
- kailash/core/actors/supervisor.py +1 -1
- kailash/core/resilience/bulkhead.py +15 -5
- kailash/core/resilience/circuit_breaker.py +74 -1
- kailash/core/resilience/health_monitor.py +433 -33
- kailash/edge/compliance.py +33 -0
- kailash/edge/consistency.py +609 -0
- kailash/edge/coordination/__init__.py +30 -0
- kailash/edge/coordination/global_ordering.py +355 -0
- kailash/edge/coordination/leader_election.py +217 -0
- kailash/edge/coordination/partition_detector.py +296 -0
- kailash/edge/coordination/raft.py +485 -0
- kailash/edge/discovery.py +63 -1
- kailash/edge/migration/__init__.py +19 -0
- kailash/edge/migration/edge_migration_service.py +384 -0
- kailash/edge/migration/edge_migrator.py +832 -0
- kailash/edge/monitoring/__init__.py +21 -0
- kailash/edge/monitoring/edge_monitor.py +736 -0
- kailash/edge/prediction/__init__.py +10 -0
- kailash/edge/prediction/predictive_warmer.py +591 -0
- kailash/edge/resource/__init__.py +102 -0
- kailash/edge/resource/cloud_integration.py +796 -0
- kailash/edge/resource/cost_optimizer.py +949 -0
- kailash/edge/resource/docker_integration.py +919 -0
- kailash/edge/resource/kubernetes_integration.py +893 -0
- kailash/edge/resource/platform_integration.py +913 -0
- kailash/edge/resource/predictive_scaler.py +959 -0
- kailash/edge/resource/resource_analyzer.py +824 -0
- kailash/edge/resource/resource_pools.py +610 -0
- kailash/integrations/dataflow_edge.py +261 -0
- kailash/mcp_server/registry_integration.py +1 -1
- kailash/mcp_server/server.py +351 -8
- kailash/mcp_server/transports.py +305 -0
- kailash/middleware/gateway/event_store.py +1 -0
- kailash/monitoring/__init__.py +18 -0
- kailash/monitoring/alerts.py +646 -0
- kailash/monitoring/metrics.py +677 -0
- kailash/nodes/__init__.py +2 -0
- kailash/nodes/ai/semantic_memory.py +2 -2
- kailash/nodes/base.py +622 -1
- kailash/nodes/code/python.py +44 -3
- kailash/nodes/data/async_sql.py +42 -20
- kailash/nodes/edge/__init__.py +36 -0
- kailash/nodes/edge/base.py +240 -0
- kailash/nodes/edge/cloud_node.py +710 -0
- kailash/nodes/edge/coordination.py +239 -0
- kailash/nodes/edge/docker_node.py +825 -0
- kailash/nodes/edge/edge_data.py +582 -0
- kailash/nodes/edge/edge_migration_node.py +396 -0
- kailash/nodes/edge/edge_monitoring_node.py +421 -0
- kailash/nodes/edge/edge_state.py +673 -0
- kailash/nodes/edge/edge_warming_node.py +393 -0
- kailash/nodes/edge/kubernetes_node.py +652 -0
- kailash/nodes/edge/platform_node.py +766 -0
- kailash/nodes/edge/resource_analyzer_node.py +378 -0
- kailash/nodes/edge/resource_optimizer_node.py +501 -0
- kailash/nodes/edge/resource_scaler_node.py +397 -0
- kailash/nodes/governance.py +410 -0
- kailash/nodes/ports.py +676 -0
- kailash/nodes/rag/registry.py +1 -1
- kailash/nodes/transaction/distributed_transaction_manager.py +48 -1
- kailash/nodes/transaction/saga_state_storage.py +2 -1
- kailash/nodes/validation.py +8 -8
- kailash/runtime/local.py +374 -1
- kailash/runtime/validation/__init__.py +12 -0
- kailash/runtime/validation/connection_context.py +119 -0
- kailash/runtime/validation/enhanced_error_formatter.py +202 -0
- kailash/runtime/validation/error_categorizer.py +164 -0
- kailash/runtime/validation/import_validator.py +446 -0
- kailash/runtime/validation/metrics.py +380 -0
- kailash/runtime/validation/performance.py +615 -0
- kailash/runtime/validation/suggestion_engine.py +212 -0
- kailash/testing/fixtures.py +2 -2
- kailash/utils/data_paths.py +74 -0
- kailash/workflow/builder.py +413 -8
- kailash/workflow/contracts.py +418 -0
- kailash/workflow/edge_infrastructure.py +369 -0
- kailash/workflow/mermaid_visualizer.py +3 -1
- kailash/workflow/migration.py +3 -3
- kailash/workflow/templates.py +6 -6
- kailash/workflow/type_inference.py +669 -0
- kailash/workflow/validation.py +134 -3
- {kailash-0.8.4.dist-info → kailash-0.8.6.dist-info}/METADATA +52 -34
- {kailash-0.8.4.dist-info → kailash-0.8.6.dist-info}/RECORD +93 -42
- kailash/nexus/__init__.py +0 -21
- kailash/nexus/cli/__init__.py +0 -5
- kailash/nexus/cli/__main__.py +0 -6
- kailash/nexus/cli/main.py +0 -176
- kailash/nexus/factory.py +0 -413
- kailash/nexus/gateway.py +0 -545
- {kailash-0.8.4.dist-info → kailash-0.8.6.dist-info}/WHEEL +0 -0
- {kailash-0.8.4.dist-info → kailash-0.8.6.dist-info}/entry_points.txt +0 -0
- {kailash-0.8.4.dist-info → kailash-0.8.6.dist-info}/licenses/LICENSE +0 -0
- {kailash-0.8.4.dist-info → kailash-0.8.6.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,119 @@
|
|
1
|
+
"""
|
2
|
+
Connection context tracking for enhanced error messages.
|
3
|
+
|
4
|
+
Provides detailed information about connection sources and targets
|
5
|
+
to enable precise error message generation with connection paths.
|
6
|
+
"""
|
7
|
+
|
8
|
+
from dataclasses import dataclass
|
9
|
+
from typing import Any, Optional
|
10
|
+
|
11
|
+
|
12
|
+
@dataclass
|
13
|
+
class ConnectionContext:
|
14
|
+
"""Context information for a specific parameter connection.
|
15
|
+
|
16
|
+
Tracks the source and target of a connection to enable detailed
|
17
|
+
error message generation with connection path reconstruction.
|
18
|
+
"""
|
19
|
+
|
20
|
+
source_node: str
|
21
|
+
"""Source node ID in the workflow"""
|
22
|
+
|
23
|
+
source_port: Optional[str]
|
24
|
+
"""Output port/parameter from source node (e.g., 'result.data')"""
|
25
|
+
|
26
|
+
target_node: str
|
27
|
+
"""Target node ID in the workflow"""
|
28
|
+
|
29
|
+
target_port: str
|
30
|
+
"""Input parameter on target node"""
|
31
|
+
|
32
|
+
parameter_value: Any
|
33
|
+
"""The actual parameter value being passed through connection"""
|
34
|
+
|
35
|
+
validation_mode: str
|
36
|
+
"""Validation mode: 'off', 'warn', or 'strict'"""
|
37
|
+
|
38
|
+
def get_connection_path(self) -> str:
|
39
|
+
"""Generate human-readable connection path string.
|
40
|
+
|
41
|
+
Returns:
|
42
|
+
Connection path in format: source_node.source_port → target_node.target_port
|
43
|
+
"""
|
44
|
+
source_part = self.source_node
|
45
|
+
if self.source_port:
|
46
|
+
source_part = f"{self.source_node}.{self.source_port}"
|
47
|
+
|
48
|
+
target_part = f"{self.target_node}.{self.target_port}"
|
49
|
+
|
50
|
+
return f"{source_part} → {target_part}"
|
51
|
+
|
52
|
+
def get_sanitized_value(self) -> str:
|
53
|
+
"""Get sanitized representation of parameter value for error messages.
|
54
|
+
|
55
|
+
Sanitizes sensitive information like SQL injection attempts, passwords, etc.
|
56
|
+
|
57
|
+
Returns:
|
58
|
+
Safe string representation of the parameter value
|
59
|
+
"""
|
60
|
+
if self.parameter_value is None:
|
61
|
+
return "None"
|
62
|
+
|
63
|
+
value_str = str(self.parameter_value)
|
64
|
+
|
65
|
+
# Detect and sanitize potential security issues
|
66
|
+
security_patterns = [
|
67
|
+
"drop table",
|
68
|
+
"delete from",
|
69
|
+
"insert into",
|
70
|
+
"update set",
|
71
|
+
"union select",
|
72
|
+
"exec(",
|
73
|
+
"eval(",
|
74
|
+
"script>",
|
75
|
+
"password",
|
76
|
+
"secret",
|
77
|
+
"token",
|
78
|
+
"key",
|
79
|
+
]
|
80
|
+
|
81
|
+
for pattern in security_patterns:
|
82
|
+
if pattern.lower() in value_str.lower():
|
83
|
+
return "**SANITIZED**"
|
84
|
+
|
85
|
+
# Truncate very long values
|
86
|
+
if len(value_str) > 100:
|
87
|
+
return f"{value_str[:97]}..."
|
88
|
+
|
89
|
+
return value_str
|
90
|
+
|
91
|
+
def is_security_sensitive(self) -> bool:
|
92
|
+
"""Check if the parameter value contains security-sensitive data.
|
93
|
+
|
94
|
+
Returns:
|
95
|
+
True if the value appears to contain sensitive information
|
96
|
+
"""
|
97
|
+
if self.parameter_value is None:
|
98
|
+
return False
|
99
|
+
|
100
|
+
value_str = str(self.parameter_value).lower()
|
101
|
+
|
102
|
+
sensitive_indicators = [
|
103
|
+
"password",
|
104
|
+
"secret",
|
105
|
+
"token",
|
106
|
+
"key",
|
107
|
+
"auth",
|
108
|
+
"drop",
|
109
|
+
"delete",
|
110
|
+
"insert",
|
111
|
+
"update",
|
112
|
+
"exec",
|
113
|
+
"union",
|
114
|
+
"select",
|
115
|
+
"script",
|
116
|
+
"eval",
|
117
|
+
]
|
118
|
+
|
119
|
+
return any(indicator in value_str for indicator in sensitive_indicators)
|
@@ -0,0 +1,202 @@
|
|
1
|
+
"""
|
2
|
+
Enhanced error message formatting for connection validation errors.
|
3
|
+
|
4
|
+
Formats validation errors into structured, readable messages with
|
5
|
+
connection paths, categorization, suggestions, and examples.
|
6
|
+
"""
|
7
|
+
|
8
|
+
from typing import Optional
|
9
|
+
|
10
|
+
from .connection_context import ConnectionContext
|
11
|
+
from .error_categorizer import ErrorCategorizer, ErrorCategory
|
12
|
+
from .suggestion_engine import ValidationSuggestion
|
13
|
+
|
14
|
+
|
15
|
+
class EnhancedErrorFormatter:
|
16
|
+
"""Formats validation errors into enhanced, actionable error messages."""
|
17
|
+
|
18
|
+
def __init__(self):
|
19
|
+
self.categorizer = ErrorCategorizer()
|
20
|
+
|
21
|
+
def format_enhanced_error(
|
22
|
+
self,
|
23
|
+
original_error: str,
|
24
|
+
error_category: ErrorCategory,
|
25
|
+
connection_context: ConnectionContext,
|
26
|
+
suggestion: Optional[ValidationSuggestion] = None,
|
27
|
+
) -> str:
|
28
|
+
"""Format a comprehensive error message with all enhancement details.
|
29
|
+
|
30
|
+
Args:
|
31
|
+
original_error: Original validation error message
|
32
|
+
error_category: Categorized error type
|
33
|
+
connection_context: Context about the failing connection
|
34
|
+
suggestion: Optional actionable suggestion
|
35
|
+
|
36
|
+
Returns:
|
37
|
+
Formatted error message with structured sections
|
38
|
+
"""
|
39
|
+
sections = []
|
40
|
+
|
41
|
+
# Header with error category
|
42
|
+
category_desc = self.categorizer.get_category_description(error_category)
|
43
|
+
severity = self.categorizer.get_severity_level(error_category)
|
44
|
+
|
45
|
+
sections.append(f"🚨 Connection Validation Error: {category_desc} [{severity}]")
|
46
|
+
sections.append("=" * 60)
|
47
|
+
|
48
|
+
# Problem section
|
49
|
+
sections.append("\n📋 Problem:")
|
50
|
+
sections.append(f" {original_error}")
|
51
|
+
|
52
|
+
# Connection path section
|
53
|
+
sections.append("\n🔗 Connection:")
|
54
|
+
connection_path = connection_context.get_connection_path()
|
55
|
+
sections.append(f" {connection_path}")
|
56
|
+
|
57
|
+
# Parameter details (sanitized)
|
58
|
+
if not connection_context.is_security_sensitive():
|
59
|
+
value_repr = connection_context.get_sanitized_value()
|
60
|
+
sections.append(f" Value: {value_repr}")
|
61
|
+
else:
|
62
|
+
sections.append(" Value: **REDACTED** (security-sensitive)")
|
63
|
+
|
64
|
+
sections.append(f" Validation Mode: {connection_context.validation_mode}")
|
65
|
+
|
66
|
+
# Suggestion section
|
67
|
+
if suggestion:
|
68
|
+
sections.append("\n💡 Suggestion:")
|
69
|
+
sections.append(f" {suggestion.message}")
|
70
|
+
|
71
|
+
# Code example
|
72
|
+
if suggestion.code_example:
|
73
|
+
sections.append("\n📝 Example:")
|
74
|
+
example_lines = suggestion.code_example.split("\n")
|
75
|
+
for line in example_lines:
|
76
|
+
sections.append(f" {line}")
|
77
|
+
|
78
|
+
# Alternative approaches
|
79
|
+
if suggestion.alternative_approaches:
|
80
|
+
sections.append("\n🔄 Alternatives:")
|
81
|
+
for i, alt in enumerate(suggestion.alternative_approaches, 1):
|
82
|
+
sections.append(f" {i}. {alt}")
|
83
|
+
|
84
|
+
# Documentation link
|
85
|
+
if suggestion.documentation_link:
|
86
|
+
sections.append("\n📚 Documentation:")
|
87
|
+
sections.append(f" {suggestion.documentation_link}")
|
88
|
+
else:
|
89
|
+
sections.append("\n💡 Suggestion:")
|
90
|
+
sections.append(" Check node documentation for parameter requirements.")
|
91
|
+
sections.append(" Verify data types and connection mapping.")
|
92
|
+
|
93
|
+
# Troubleshooting tips
|
94
|
+
sections.append("\n🛠️ Quick Troubleshooting:")
|
95
|
+
sections.append(" 1. Check the source node output format")
|
96
|
+
sections.append(" 2. Verify target node parameter requirements")
|
97
|
+
sections.append(" 3. Test with simplified data first")
|
98
|
+
sections.append(
|
99
|
+
" 4. Review connection syntax: workflow.add_connection(source, source_port, target, target_port)"
|
100
|
+
)
|
101
|
+
|
102
|
+
return "\n".join(sections)
|
103
|
+
|
104
|
+
def format_simple_error(
|
105
|
+
self, original_error: str, connection_context: ConnectionContext
|
106
|
+
) -> str:
|
107
|
+
"""Format a simple enhanced error message for warn mode.
|
108
|
+
|
109
|
+
Args:
|
110
|
+
original_error: Original validation error message
|
111
|
+
connection_context: Context about the failing connection
|
112
|
+
|
113
|
+
Returns:
|
114
|
+
Simple formatted error message
|
115
|
+
"""
|
116
|
+
connection_path = connection_context.get_connection_path()
|
117
|
+
return f"Connection validation warning: {connection_path} - {original_error}"
|
118
|
+
|
119
|
+
def format_security_error(
|
120
|
+
self,
|
121
|
+
original_error: str,
|
122
|
+
connection_context: ConnectionContext,
|
123
|
+
suggestion: Optional[ValidationSuggestion] = None,
|
124
|
+
) -> str:
|
125
|
+
"""Format security-specific error message with appropriate warnings.
|
126
|
+
|
127
|
+
Args:
|
128
|
+
original_error: Original security error message
|
129
|
+
connection_context: Context about the failing connection
|
130
|
+
suggestion: Optional security-specific suggestion
|
131
|
+
|
132
|
+
Returns:
|
133
|
+
Security-focused error message
|
134
|
+
"""
|
135
|
+
sections = []
|
136
|
+
|
137
|
+
sections.append("🔒 SECURITY ALERT: Potential Security Vulnerability")
|
138
|
+
sections.append("=" * 60)
|
139
|
+
|
140
|
+
sections.append("\n⚠️ Security Issue:")
|
141
|
+
sections.append(f" {original_error}")
|
142
|
+
|
143
|
+
sections.append("\n🔗 Affected Connection:")
|
144
|
+
connection_path = connection_context.get_connection_path()
|
145
|
+
sections.append(f" {connection_path}")
|
146
|
+
|
147
|
+
# Always redact security-sensitive values
|
148
|
+
sections.append(" Value: **REDACTED** (potential security risk)")
|
149
|
+
|
150
|
+
if suggestion:
|
151
|
+
sections.append("\n🛡️ Security Recommendation:")
|
152
|
+
sections.append(f" {suggestion.message}")
|
153
|
+
|
154
|
+
if suggestion.code_example:
|
155
|
+
sections.append("\n🔐 Secure Example:")
|
156
|
+
example_lines = suggestion.code_example.split("\n")
|
157
|
+
for line in example_lines:
|
158
|
+
sections.append(f" {line}")
|
159
|
+
|
160
|
+
sections.append("\n🚨 Immediate Actions:")
|
161
|
+
sections.append(" 1. Review the data source for potential attacks")
|
162
|
+
sections.append(" 2. Implement input validation and sanitization")
|
163
|
+
sections.append(" 3. Use parameterized queries for database operations")
|
164
|
+
sections.append(" 4. Consider implementing rate limiting")
|
165
|
+
|
166
|
+
sections.append("\n📋 Security Checklist:")
|
167
|
+
sections.append(" □ Input validation implemented")
|
168
|
+
sections.append(" □ Output encoding applied")
|
169
|
+
sections.append(" □ Parameterized queries used")
|
170
|
+
sections.append(" □ Access controls verified")
|
171
|
+
|
172
|
+
return "\n".join(sections)
|
173
|
+
|
174
|
+
def get_error_summary(
|
175
|
+
self, error_category: ErrorCategory, connection_context: ConnectionContext
|
176
|
+
) -> str:
|
177
|
+
"""Get a brief summary of the error for logging.
|
178
|
+
|
179
|
+
Args:
|
180
|
+
error_category: Categorized error type
|
181
|
+
connection_context: Context about the failing connection
|
182
|
+
|
183
|
+
Returns:
|
184
|
+
Brief error summary
|
185
|
+
"""
|
186
|
+
category_desc = self.categorizer.get_category_description(error_category)
|
187
|
+
connection_path = connection_context.get_connection_path()
|
188
|
+
|
189
|
+
return f"{category_desc}: {connection_path}"
|
190
|
+
|
191
|
+
def _indent_lines(self, text: str, indent: str = " ") -> str:
|
192
|
+
"""Indent all lines in text with the given prefix.
|
193
|
+
|
194
|
+
Args:
|
195
|
+
text: Text to indent
|
196
|
+
indent: Indentation string
|
197
|
+
|
198
|
+
Returns:
|
199
|
+
Indented text
|
200
|
+
"""
|
201
|
+
lines = text.split("\n")
|
202
|
+
return "\n".join(f"{indent}{line}" for line in lines)
|
@@ -0,0 +1,164 @@
|
|
1
|
+
"""
|
2
|
+
Error categorization for connection validation failures.
|
3
|
+
|
4
|
+
Classifies validation errors into specific categories to enable
|
5
|
+
targeted suggestion generation and better error handling.
|
6
|
+
"""
|
7
|
+
|
8
|
+
import re
|
9
|
+
from enum import Enum
|
10
|
+
from typing import Any, Optional
|
11
|
+
|
12
|
+
|
13
|
+
class ErrorCategory(Enum):
|
14
|
+
"""Categories of connection validation errors."""
|
15
|
+
|
16
|
+
TYPE_MISMATCH = "type_mismatch"
|
17
|
+
"""Parameter type doesn't match expected type"""
|
18
|
+
|
19
|
+
MISSING_PARAMETER = "missing_parameter"
|
20
|
+
"""Required parameter is missing or None"""
|
21
|
+
|
22
|
+
CONSTRAINT_VIOLATION = "constraint_violation"
|
23
|
+
"""Parameter violates validation constraints (range, format, etc.)"""
|
24
|
+
|
25
|
+
SECURITY_VIOLATION = "security_violation"
|
26
|
+
"""Parameter contains potential security issues (injection, etc.)"""
|
27
|
+
|
28
|
+
UNKNOWN = "unknown"
|
29
|
+
"""Error category could not be determined"""
|
30
|
+
|
31
|
+
|
32
|
+
class ErrorCategorizer:
|
33
|
+
"""Categorizes validation errors for enhanced error message generation."""
|
34
|
+
|
35
|
+
# Error patterns for categorization
|
36
|
+
TYPE_ERROR_PATTERNS = [
|
37
|
+
r"expected .+ but got .+",
|
38
|
+
r"object of type .+ has no attribute",
|
39
|
+
r"unsupported operand type",
|
40
|
+
r"can't convert .+ to .+",
|
41
|
+
r"'[^']+' object .+ not .+",
|
42
|
+
r"argument must be .+, not .+",
|
43
|
+
]
|
44
|
+
|
45
|
+
MISSING_PARAMETER_PATTERNS = [
|
46
|
+
r"missing required parameter",
|
47
|
+
r"required argument .+ is missing",
|
48
|
+
r"takes .+ arguments but .+ were given",
|
49
|
+
r"missing .+ required",
|
50
|
+
r"parameter .+ is required",
|
51
|
+
]
|
52
|
+
|
53
|
+
CONSTRAINT_VIOLATION_PATTERNS = [
|
54
|
+
r"must be positive",
|
55
|
+
r"must be greater than",
|
56
|
+
r"must be less than",
|
57
|
+
r"invalid value",
|
58
|
+
r"out of range",
|
59
|
+
r"violates constraint",
|
60
|
+
r"exceeds maximum",
|
61
|
+
r"below minimum",
|
62
|
+
]
|
63
|
+
|
64
|
+
SECURITY_VIOLATION_PATTERNS = [
|
65
|
+
r"sql injection",
|
66
|
+
r"injection detected",
|
67
|
+
r"security violation",
|
68
|
+
r"potential attack",
|
69
|
+
r"malicious",
|
70
|
+
r"dangerous",
|
71
|
+
r"unsafe",
|
72
|
+
r"script injection",
|
73
|
+
]
|
74
|
+
|
75
|
+
def categorize_error(
|
76
|
+
self, error: Exception, node_type: Optional[str] = None
|
77
|
+
) -> ErrorCategory:
|
78
|
+
"""Categorize a validation error based on error message and context.
|
79
|
+
|
80
|
+
Args:
|
81
|
+
error: The validation error exception
|
82
|
+
node_type: Optional node type for additional context
|
83
|
+
|
84
|
+
Returns:
|
85
|
+
ErrorCategory enum value indicating the error type
|
86
|
+
"""
|
87
|
+
error_message = str(error).lower()
|
88
|
+
error_type = type(error).__name__
|
89
|
+
|
90
|
+
# Check for security violations first (highest priority)
|
91
|
+
if self._matches_patterns(error_message, self.SECURITY_VIOLATION_PATTERNS):
|
92
|
+
return ErrorCategory.SECURITY_VIOLATION
|
93
|
+
|
94
|
+
# Check for type errors
|
95
|
+
if error_type in ["TypeError", "AttributeError"] or self._matches_patterns(
|
96
|
+
error_message, self.TYPE_ERROR_PATTERNS
|
97
|
+
):
|
98
|
+
return ErrorCategory.TYPE_MISMATCH
|
99
|
+
|
100
|
+
# Check for missing parameter errors
|
101
|
+
if error_type in ["ValueError", "TypeError"] and self._matches_patterns(
|
102
|
+
error_message, self.MISSING_PARAMETER_PATTERNS
|
103
|
+
):
|
104
|
+
return ErrorCategory.MISSING_PARAMETER
|
105
|
+
|
106
|
+
# Check for constraint violations
|
107
|
+
if error_type == "ValueError" and self._matches_patterns(
|
108
|
+
error_message, self.CONSTRAINT_VIOLATION_PATTERNS
|
109
|
+
):
|
110
|
+
return ErrorCategory.CONSTRAINT_VIOLATION
|
111
|
+
|
112
|
+
# Default to unknown if no pattern matches
|
113
|
+
return ErrorCategory.UNKNOWN
|
114
|
+
|
115
|
+
def _matches_patterns(self, text: str, patterns: list[str]) -> bool:
|
116
|
+
"""Check if text matches any of the given regex patterns.
|
117
|
+
|
118
|
+
Args:
|
119
|
+
text: Text to check
|
120
|
+
patterns: List of regex patterns
|
121
|
+
|
122
|
+
Returns:
|
123
|
+
True if text matches any pattern
|
124
|
+
"""
|
125
|
+
for pattern in patterns:
|
126
|
+
if re.search(pattern, text, re.IGNORECASE):
|
127
|
+
return True
|
128
|
+
return False
|
129
|
+
|
130
|
+
def get_category_description(self, category: ErrorCategory) -> str:
|
131
|
+
"""Get human-readable description of error category.
|
132
|
+
|
133
|
+
Args:
|
134
|
+
category: Error category enum
|
135
|
+
|
136
|
+
Returns:
|
137
|
+
Human-readable description
|
138
|
+
"""
|
139
|
+
descriptions = {
|
140
|
+
ErrorCategory.TYPE_MISMATCH: "Type Mismatch",
|
141
|
+
ErrorCategory.MISSING_PARAMETER: "Missing Required Parameter",
|
142
|
+
ErrorCategory.CONSTRAINT_VIOLATION: "Parameter Constraint Violation",
|
143
|
+
ErrorCategory.SECURITY_VIOLATION: "Security Violation",
|
144
|
+
ErrorCategory.UNKNOWN: "Unknown Validation Error",
|
145
|
+
}
|
146
|
+
return descriptions.get(category, "Unknown Error")
|
147
|
+
|
148
|
+
def get_severity_level(self, category: ErrorCategory) -> str:
|
149
|
+
"""Get severity level for error category.
|
150
|
+
|
151
|
+
Args:
|
152
|
+
category: Error category enum
|
153
|
+
|
154
|
+
Returns:
|
155
|
+
Severity level: 'CRITICAL', 'HIGH', 'MEDIUM', 'LOW'
|
156
|
+
"""
|
157
|
+
severity_map = {
|
158
|
+
ErrorCategory.SECURITY_VIOLATION: "CRITICAL",
|
159
|
+
ErrorCategory.MISSING_PARAMETER: "HIGH",
|
160
|
+
ErrorCategory.TYPE_MISMATCH: "MEDIUM",
|
161
|
+
ErrorCategory.CONSTRAINT_VIOLATION: "MEDIUM",
|
162
|
+
ErrorCategory.UNKNOWN: "LOW",
|
163
|
+
}
|
164
|
+
return severity_map.get(category, "LOW")
|