Currently, Valkyrie uses standard Python exceptions. To improve robustness, maintainability, and error clarity, we need to implement a hierarchy of custom exceptions specific to Valkyrie's domain.
🎯 Goals
- Centralize error handling in
valkyrie.utils.exceptions
- Improve the precision of error messages for users
- Facilitate debugging and error handling
- Create a solid foundation for future extensions
📋 Todo
1. Create the Exceptions Module
# valkyrie/utils/exceptions.py
"""
Custom exceptions hierarchy for Valkyrie.
"""
class ValkyrieError(Exception):
"""Base exception for all Valkyrie-specific errors."""
pass
# Add specific exception classes here...
2. Implement Exception Categories
Core Exceptions:
class ConfigurationError(ValkyrieError):
"""Raised when configuration is invalid or missing."""
class RuleError(ValkyrieError):
"""Base exception for rule-related errors."""
class ScanError(ValkyrieError):
"""Base exception for scanning-related errors."""
Rule-Specific Exceptions:
class RuleValidationError(RuleError):
"""Raised when a rule fails validation."""
class RuleExecutionError(RuleError):
"""Raised when a rule fails during execution."""
class RuleNotFoundError(RuleError):
"""Raised when a requested rule is not found."""
...
Scan-Specific Exceptions:
class FileScanError(ScanError):
"""Raised when file scanning fails."""
class DirectoryScanError(ScanError):
"""Raised when directory scanning fails."""
class TimeoutError(ScanError):
"""Raised when a scan operation times out."""
...
CI/CD Exceptions:
class CIAdapterError(ValkyrieError):
"""Base exception for CI adapter errors."""
...
✅ Acceptance Criteria
🔧 Technical Details
Recommended Structure:
class ValkyrieError(Exception):
"""Base exception with optional error code and context."""
def __init__(self, message: str, code: Optional[str] = None, context: Optional[Dict] = None):
self.code = code
self.context = context or {}
super().__init__(message)
class ConfigurationError(ValkyrieError):
"""Configuration-related errors."""
def __init__(self, message: str, config_path: Optional[str] = None):
context = {"config_path": config_path} if config_path else {}
super().__init__(message, "CONFIG_ERROR", context)
📚 Documentation
Update:
🧪 Testing
Create tests/utils/test_exceptions.py:
def test_valkyrie_error_creation():
"""Test basic exception functionality."""
error = ValkyrieError("Test message", "TEST_CODE", {"key": "value"})
assert str(error) == "Test message"
assert error.code == "TEST_CODE"
assert error.context["key"] == "value"
💡 Additional Notes
- Use constant error codes to facilitate integration
- Plan for an error contextualization system
- Keep error messages informative but concise
Currently, Valkyrie uses standard Python exceptions. To improve robustness, maintainability, and error clarity, we need to implement a hierarchy of custom exceptions specific to Valkyrie's domain.
🎯 Goals
valkyrie.utils.exceptions📋 Todo
1. Create the Exceptions Module
2. Implement Exception Categories
Core Exceptions:
Rule-Specific Exceptions:
Scan-Specific Exceptions:
CI/CD Exceptions:
✅ Acceptance Criteria
valkyrie.utils.exceptionsmodule exists with a complete hierarchyValkyrieError🔧 Technical Details
Recommended Structure:
📚 Documentation
Update:
docs/error_codes.md- List of error codesdocs/development.md- Error handling guideexamples/error_handling.py- Usage example🧪 Testing
Create
tests/utils/test_exceptions.py:💡 Additional Notes