exceptions.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. """Custom exception classes for the boilerplates CLI.
  2. This module defines specific exception types for better error handling
  3. and diagnostics throughout the application.
  4. """
  5. from typing import Optional, List, Dict
  6. class BoilerplatesError(Exception):
  7. """Base exception for all boilerplates CLI errors."""
  8. pass
  9. class ConfigError(BoilerplatesError):
  10. """Raised when configuration operations fail."""
  11. pass
  12. class ConfigValidationError(ConfigError):
  13. """Raised when configuration validation fails."""
  14. pass
  15. class TemplateError(BoilerplatesError):
  16. """Base exception for template-related errors."""
  17. pass
  18. class TemplateNotFoundError(TemplateError):
  19. """Raised when a template cannot be found."""
  20. def __init__(self, template_id: str, module_name: Optional[str] = None):
  21. self.template_id = template_id
  22. self.module_name = module_name
  23. msg = f"Template '{template_id}' not found"
  24. if module_name:
  25. msg += f" in module '{module_name}'"
  26. super().__init__(msg)
  27. class TemplateLoadError(TemplateError):
  28. """Raised when a template fails to load."""
  29. pass
  30. class TemplateSyntaxError(TemplateError):
  31. """Raised when a Jinja2 template has syntax errors."""
  32. def __init__(self, template_id: str, errors: List[str]):
  33. self.template_id = template_id
  34. self.errors = errors
  35. msg = f"Jinja2 syntax errors in template '{template_id}':\n" + "\n".join(errors)
  36. super().__init__(msg)
  37. class TemplateValidationError(TemplateError):
  38. """Raised when template validation fails."""
  39. pass
  40. class TemplateRenderError(TemplateError):
  41. """Raised when template rendering fails."""
  42. def __init__(
  43. self,
  44. message: str,
  45. file_path: Optional[str] = None,
  46. line_number: Optional[int] = None,
  47. column: Optional[int] = None,
  48. context_lines: Optional[List[str]] = None,
  49. variable_context: Optional[Dict[str, str]] = None,
  50. suggestions: Optional[List[str]] = None,
  51. original_error: Optional[Exception] = None
  52. ):
  53. self.file_path = file_path
  54. self.line_number = line_number
  55. self.column = column
  56. self.context_lines = context_lines or []
  57. self.variable_context = variable_context or {}
  58. self.suggestions = suggestions or []
  59. self.original_error = original_error
  60. # Build enhanced error message
  61. parts = [message]
  62. if file_path:
  63. location = f"File: {file_path}"
  64. if line_number:
  65. location += f", Line: {line_number}"
  66. if column:
  67. location += f", Column: {column}"
  68. parts.append(location)
  69. super().__init__("\n".join(parts))
  70. class VariableError(BoilerplatesError):
  71. """Base exception for variable-related errors."""
  72. pass
  73. class VariableValidationError(VariableError):
  74. """Raised when variable validation fails."""
  75. def __init__(self, variable_name: str, message: str):
  76. self.variable_name = variable_name
  77. msg = f"Validation error for variable '{variable_name}': {message}"
  78. super().__init__(msg)
  79. class VariableTypeError(VariableError):
  80. """Raised when a variable has an incorrect type."""
  81. def __init__(self, variable_name: str, expected_type: str, actual_type: str):
  82. self.variable_name = variable_name
  83. self.expected_type = expected_type
  84. self.actual_type = actual_type
  85. msg = f"Type error for variable '{variable_name}': expected {expected_type}, got {actual_type}"
  86. super().__init__(msg)
  87. class LibraryError(BoilerplatesError):
  88. """Raised when library operations fail."""
  89. pass
  90. class ModuleError(BoilerplatesError):
  91. """Raised when module operations fail."""
  92. pass
  93. class ModuleNotFoundError(ModuleError):
  94. """Raised when a module cannot be found."""
  95. def __init__(self, module_name: str):
  96. self.module_name = module_name
  97. msg = f"Module '{module_name}' not found"
  98. super().__init__(msg)
  99. class ModuleLoadError(ModuleError):
  100. """Raised when a module fails to load."""
  101. pass
  102. class FileOperationError(BoilerplatesError):
  103. """Raised when file operations fail."""
  104. pass
  105. class RenderError(BoilerplatesError):
  106. """Raised when rendering operations fail."""
  107. pass
  108. class YAMLParseError(BoilerplatesError):
  109. """Raised when YAML parsing fails."""
  110. def __init__(self, file_path: str, original_error: Exception):
  111. self.file_path = file_path
  112. self.original_error = original_error
  113. msg = f"Failed to parse YAML file '{file_path}': {original_error}"
  114. super().__init__(msg)