Coverage for src/prosemark/templates/domain/exceptions/template_exceptions.py: 100%

64 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-10-01 00:05 +0000

1"""Template-specific exceptions for the templates domain. 

2 

3These exceptions represent various error conditions that can occur 

4during template operations, validation, and instantiation. 

5""" 

6 

7 

8class TemplateError(Exception): 

9 """Base exception for all template-related errors.""" 

10 

11 def __init__(self, message: str, template_path: str | None = None) -> None: 

12 """Initialize template error. 

13 

14 Args: 

15 message: Human-readable error description 

16 template_path: Optional path to the template that caused the error 

17 

18 """ 

19 self.template_path = template_path 

20 if template_path: 

21 super().__init__(f'{message} (template: {template_path})') 

22 else: 

23 super().__init__(message) 

24 

25 

26class TemplateNotFoundError(TemplateError): 

27 """Raised when a requested template cannot be found.""" 

28 

29 def __init__(self, template_name: str, search_path: str | None = None) -> None: 

30 """Initialize template not found error. 

31 

32 Args: 

33 template_name: Name of the template that was not found 

34 search_path: Directory where template was searched for 

35 

36 """ 

37 self.template_name = template_name 

38 self.search_path = search_path 

39 

40 if search_path: 

41 message = f"Template '{template_name}' not found in directory '{search_path}'" 

42 else: 

43 message = f"Template '{template_name}' not found" 

44 

45 super().__init__(message) 

46 

47 

48class TemplateDirectoryNotFoundError(TemplateError): 

49 """Raised when the templates directory does not exist.""" 

50 

51 def __init__(self, directory_path: str) -> None: 

52 """Initialize template directory not found error. 

53 

54 Args: 

55 directory_path: Path to the directory that does not exist 

56 

57 """ 

58 self.directory_path = directory_path 

59 message = f'Templates directory not found: {directory_path}' 

60 super().__init__(message) 

61 

62 

63class EmptyTemplateDirectoryError(TemplateError): 

64 """Raised when a template directory contains no valid templates.""" 

65 

66 def __init__(self, directory_path: str) -> None: 

67 """Initialize empty template directory error. 

68 

69 Args: 

70 directory_path: Path to the empty template directory 

71 

72 """ 

73 self.directory_path = directory_path 

74 message = f'Template directory contains no valid templates: {directory_path}' 

75 super().__init__(message) 

76 

77 

78class InvalidTemplateDirectoryError(TemplateError): 

79 """Raised when a template directory contains invalid templates.""" 

80 

81 def __init__(self, directory_path: str, invalid_templates: list[str]) -> None: 

82 """Initialize invalid template directory error. 

83 

84 Args: 

85 directory_path: Path to the template directory 

86 invalid_templates: List of invalid template file names 

87 

88 """ 

89 self.directory_path = directory_path 

90 self.invalid_templates = invalid_templates 

91 

92 invalid_list = ', '.join(invalid_templates) 

93 message = f'Template directory contains invalid templates: {invalid_list} (in {directory_path})' 

94 super().__init__(message) 

95 

96 

97class TemplateParseError(TemplateError): 

98 """Raised when template content cannot be parsed.""" 

99 

100 def __init__(self, message: str, template_path: str | None = None, line_number: int | None = None) -> None: 

101 """Initialize template parse error. 

102 

103 Args: 

104 message: Specific parsing error description 

105 template_path: Path to the template with parse error 

106 line_number: Optional line number where error occurred 

107 

108 """ 

109 self.line_number = line_number 

110 

111 full_message = f'{message} at line {line_number}' if line_number and template_path else message 

112 

113 super().__init__(full_message, template_path) 

114 

115 

116class TemplateValidationError(TemplateError): 

117 """Raised when template content fails validation.""" 

118 

119 def __init__(self, message: str, template_path: str | None = None, validation_rule: str | None = None) -> None: 

120 """Initialize template validation error. 

121 

122 Args: 

123 message: Validation error description 

124 template_path: Path to the template that failed validation 

125 validation_rule: Optional name of the validation rule that failed 

126 

127 """ 

128 self.validation_rule = validation_rule 

129 

130 full_message = f'{message} (validation rule: {validation_rule})' if validation_rule else message 

131 

132 super().__init__(full_message, template_path) 

133 

134 

135class InvalidPlaceholderError(TemplateError): 

136 """Raised when a placeholder has invalid syntax or properties.""" 

137 

138 def __init__(self, message: str, placeholder_pattern: str | None = None, template_path: str | None = None) -> None: 

139 """Initialize invalid placeholder error. 

140 

141 Args: 

142 message: Placeholder error description 

143 placeholder_pattern: The invalid placeholder pattern 

144 template_path: Path to template containing the invalid placeholder 

145 

146 """ 

147 self.placeholder_pattern = placeholder_pattern 

148 

149 full_message = f'{message} (placeholder: {placeholder_pattern})' if placeholder_pattern else message 

150 

151 super().__init__(full_message, template_path) 

152 

153 

154class InvalidPlaceholderValueError(TemplateError): 

155 """Raised when a user-provided placeholder value is invalid.""" 

156 

157 def __init__(self, message: str, placeholder_name: str | None = None, provided_value: str | None = None) -> None: 

158 """Initialize invalid placeholder value error. 

159 

160 Args: 

161 message: Value validation error description 

162 placeholder_name: Name of the placeholder with invalid value 

163 provided_value: The invalid value that was provided 

164 

165 """ 

166 self.placeholder_name = placeholder_name 

167 self.provided_value = provided_value 

168 

169 if placeholder_name and provided_value: 

170 full_message = f"{message} (placeholder: {placeholder_name}, value: '{provided_value}')" 

171 elif placeholder_name: 

172 full_message = f'{message} (placeholder: {placeholder_name})' 

173 else: 

174 full_message = message 

175 

176 super().__init__(full_message) 

177 

178 

179class UserCancelledError(TemplateError): 

180 """Raised when user cancels template operation.""" 

181 

182 def __init__(self, message: str = 'Operation cancelled by user') -> None: 

183 """Initialize user cancelled error. 

184 

185 Args: 

186 message: Cancellation message 

187 

188 """ 

189 super().__init__(message) 

190 

191 

192class PlaceholderProcessingError(TemplateError): 

193 """Raised when placeholder replacement fails.""" 

194 

195 def __init__(self, message: str, placeholder_name: str | None = None, template_path: str | None = None) -> None: 

196 """Initialize placeholder processing error. 

197 

198 Args: 

199 message: Processing error description 

200 placeholder_name: Name of placeholder that failed processing 

201 template_path: Path to template being processed 

202 

203 """ 

204 self.placeholder_name = placeholder_name 

205 

206 full_message = f'{message} (placeholder: {placeholder_name})' if placeholder_name else message 

207 

208 super().__init__(full_message, template_path)