1use std::path::PathBuf;
2use std::fmt;
3use thiserror::Error;
4use crate::dna::atp::lexer::SourceLocation;
5#[derive(Error, Debug, Clone)]
6pub enum HlxError {
7 #[error("Configuration conversion failed: {field} - {details}")]
8 ConfigConversion { field: String, details: String, suggestion: String },
9 #[error("Dataset processing failed: {message}")]
10 DatasetProcessing { message: String, suggestion: String },
11 #[error("Dataset quality validation failed: score {score:.2}")]
12 QualityValidation { score: f64, issues: Vec<String>, suggestions: Vec<String> },
13 #[error("Format conversion failed: {from} → {to}")]
14 FormatConversion { from: String, to: String, suggestion: String },
15 #[error("Algorithm '{algorithm}' not supported")]
16 UnsupportedAlgorithm { algorithm: String, supported: Vec<String> },
17 #[error("Dataset not found: {path}")]
18 DatasetNotFound { path: PathBuf, suggestion: String },
19 #[error("HLX processing failed: {message}")]
20 HlxProcessing { message: String, suggestion: String },
21 #[error("Forge integration failed: {message}")]
22 ForgeIntegration { message: String, suggestion: String },
23 #[error("Configuration validation failed: {field} = {value}")]
24 ConfigValidation { field: String, value: String, suggestion: String },
25 #[error("Invalid input: {message}")]
26 InvalidInput { message: String, suggestion: String },
27 #[error("Execution error: {message}")]
28 ExecutionError { message: String, suggestion: String },
29 #[error("Invalid parameters: {message}")]
30 InvalidParameters { message: String, suggestion: String },
31 #[error("Unknown operator: {message}")]
32 UnknownOperator { message: String, suggestion: String },
33 #[error("Validation error: {message}")]
34 ValidationError { message: String, suggestion: String },
35 #[error("Hash error: {message}")]
36 HashError { message: String, suggestion: String },
37 #[error("JSON error: {message}")]
38 JsonError { message: String, suggestion: String },
39 #[error("Base64 error: {message}")]
40 Base64Error { message: String, suggestion: String },
41 #[error("Unknown error: {message}")]
42 Unknown { message: String, suggestion: String },
43 #[error("Compilation error: {message}")]
44 Compilation { message: String, suggestion: String },
45 #[error("IO error: {message}")]
46 Io { message: String, suggestion: String },
47 #[error("Serialization error: {message}")]
48 SerializationError { message: String, suggestion: String },
49 #[error("Deserialization error: {message}")]
50 DeserializationError { message: String, suggestion: String },
51 #[error("Compression error: {message}")]
52 CompressionError { message: String, suggestion: String },
53 #[error("Decompression error: {message}")]
54 DecompressionError { message: String, suggestion: String },
55 #[error("Feature not available: {feature}")]
56 FeatureError { feature: String, message: String },
57}
58impl HlxError {
59 pub fn config_conversion(
60 field: impl Into<String>,
61 details: impl Into<String>,
62 ) -> Self {
63 let field = field.into();
64 let details = details.into();
65 let suggestion = format!(
66 "Check your Forge.toml configuration for the '{}' field", field
67 );
68 Self::ConfigConversion {
69 field,
70 details,
71 suggestion,
72 }
73 }
74 pub fn dataset_processing(message: impl Into<String>) -> Self {
75 let message = message.into();
76 let suggestion = "Try running 'forge hlx dataset validate' to check dataset compatibility"
77 .to_string();
78 Self::DatasetProcessing {
79 message,
80 suggestion,
81 }
82 }
83 pub fn quality_validation(score: f64, issues: Vec<String>) -> Self {
84 let suggestions = vec![
85 "Run 'forge hlx dataset analyze' for detailed quality metrics".to_string(),
86 "Consider filtering or augmenting low-quality samples".to_string(),
87 "Check dataset format and required columns".to_string(),
88 ];
89 Self::QualityValidation {
90 score,
91 issues,
92 suggestions,
93 }
94 }
95 pub fn format_conversion(from: impl Into<String>, to: impl Into<String>) -> Self {
96 let from = from.into();
97 let to = to.into();
98 let suggestion = format!(
99 "Ensure your dataset contains the required fields for {} format", to
100 );
101 Self::FormatConversion {
102 from,
103 to,
104 suggestion,
105 }
106 }
107 pub fn unsupported_algorithm(algorithm: impl Into<String>) -> Self {
108 let algorithm = algorithm.into();
109 let supported = vec!["bco", "dpo", "ppo", "sft"]
110 .into_iter()
111 .map(String::from)
112 .collect();
113 Self::UnsupportedAlgorithm {
114 algorithm,
115 supported,
116 }
117 }
118 pub fn dataset_not_found(path: PathBuf) -> Self {
119 let suggestion = format!(
120 "Ensure the dataset file exists at: {}", path.display()
121 );
122 Self::DatasetNotFound {
123 path,
124 suggestion,
125 }
126 }
127 pub fn execution_error(
128 message: impl Into<String>,
129 suggestion: impl Into<String>,
130 ) -> Self {
131 let message = message.into();
132 let suggestion = suggestion.into();
133 Self::ExecutionError {
134 message,
135 suggestion,
136 }
137 }
138 pub fn invalid_input(
139 message: impl Into<String>,
140 suggestion: impl Into<String>,
141 ) -> Self {
142 let message = message.into();
143 let suggestion = suggestion.into();
144 Self::InvalidInput {
145 message,
146 suggestion,
147 }
148 }
149 pub fn invalid_parameters(operator: &str, params: &str) -> Self {
150 let message = format!(
151 "Invalid parameters for operator '{}': {}", operator, params
152 );
153 let suggestion = format!("Check the operator '{}' parameter format", operator);
154 Self::InvalidParameters {
155 message,
156 suggestion,
157 }
158 }
159 pub fn unknown_operator(operator: impl Into<String>) -> Self {
160 let operator = operator.into();
161 let message = format!("Unknown operator: {}", operator);
162 let suggestion = "Check the operator name and ensure it is supported"
163 .to_string();
164 Self::UnknownOperator {
165 message,
166 suggestion,
167 }
168 }
169 pub fn validation_error(
170 message: impl Into<String>,
171 suggestion: impl Into<String>,
172 ) -> Self {
173 let message = message.into();
174 let suggestion = suggestion.into();
175 Self::ValidationError {
176 message,
177 suggestion,
178 }
179 }
180 pub fn hash_error(
181 message: impl Into<String>,
182 suggestion: impl Into<String>,
183 ) -> Self {
184 let message = message.into();
185 let suggestion = suggestion.into();
186 Self::HashError {
187 message,
188 suggestion,
189 }
190 }
191 pub fn json_error(
192 message: impl Into<String>,
193 suggestion: impl Into<String>,
194 ) -> Self {
195 let message = message.into();
196 let suggestion = suggestion.into();
197 Self::JsonError {
198 message,
199 suggestion,
200 }
201 }
202 pub fn base64_error(
203 message: impl Into<String>,
204 suggestion: impl Into<String>,
205 ) -> Self {
206 let message = message.into();
207 let suggestion = suggestion.into();
208 Self::Base64Error {
209 message,
210 suggestion,
211 }
212 }
213 pub fn unknown_error(
214 message: impl Into<String>,
215 suggestion: impl Into<String>,
216 ) -> Self {
217 let message = message.into();
218 let suggestion = suggestion.into();
219 Self::Unknown {
220 message,
221 suggestion,
222 }
223 }
224 pub fn compilation_error(
225 message: impl Into<String>,
226 suggestion: impl Into<String>,
227 ) -> Self {
228 let message = message.into();
229 let suggestion = suggestion.into();
230 Self::Compilation {
231 message,
232 suggestion,
233 }
234 }
235 pub fn io_error(message: impl Into<String>, suggestion: impl Into<String>) -> Self {
236 let message = message.into();
237 let suggestion = suggestion.into();
238 Self::Io { message, suggestion }
239 }
240 pub fn serialization_error(
241 message: impl Into<String>,
242 suggestion: impl Into<String>,
243 ) -> Self {
244 let message = message.into();
245 let suggestion = suggestion.into();
246 Self::SerializationError {
247 message,
248 suggestion,
249 }
250 }
251 pub fn deserialization_error(
252 message: impl Into<String>,
253 suggestion: impl Into<String>,
254 ) -> Self {
255 let message = message.into();
256 let suggestion = suggestion.into();
257 Self::DeserializationError {
258 message,
259 suggestion,
260 }
261 }
262 pub fn compression_error(
263 message: impl Into<String>,
264 suggestion: impl Into<String>,
265 ) -> Self {
266 let message = message.into();
267 let suggestion = suggestion.into();
268 Self::CompressionError {
269 message,
270 suggestion,
271 }
272 }
273 pub fn decompression_error(
274 message: impl Into<String>,
275 suggestion: impl Into<String>,
276 ) -> Self {
277 let message = message.into();
278 let suggestion = suggestion.into();
279 Self::DecompressionError {
280 message,
281 suggestion,
282 }
283 }
284 pub fn feature_error(
285 feature: impl Into<String>,
286 message: impl Into<String>,
287 ) -> Self {
288 let feature = feature.into();
289 let message = message.into();
290 Self::FeatureError {
291 feature,
292 message,
293 }
294 }
295 pub fn suggestions(&self) -> Vec<String> {
296 match self {
297 Self::ConfigConversion { suggestion, .. } => vec![suggestion.clone()],
298 Self::DatasetProcessing { suggestion, .. } => vec![suggestion.clone()],
299 Self::QualityValidation { suggestions, .. } => suggestions.clone(),
300 Self::FormatConversion { suggestion, .. } => vec![suggestion.clone()],
301 Self::UnsupportedAlgorithm { supported, .. } => {
302 vec![format!("Supported algorithms: {}", supported.join(", "))]
303 }
304 Self::DatasetNotFound { suggestion, .. } => vec![suggestion.clone()],
305 Self::HlxProcessing { suggestion, .. } => vec![suggestion.clone()],
306 Self::ForgeIntegration { suggestion, .. } => vec![suggestion.clone()],
307 Self::ConfigValidation { suggestion, .. } => vec![suggestion.clone()],
308 Self::InvalidInput { suggestion, .. } => vec![suggestion.clone()],
309 Self::ExecutionError { suggestion, .. } => vec![suggestion.clone()],
310 Self::InvalidParameters { suggestion, .. } => vec![suggestion.clone()],
311 Self::UnknownOperator { suggestion, .. } => vec![suggestion.clone()],
312 Self::ValidationError { suggestion, .. } => vec![suggestion.clone()],
313 Self::HashError { suggestion, .. } => vec![suggestion.clone()],
314 Self::JsonError { suggestion, .. } => vec![suggestion.clone()],
315 Self::Base64Error { suggestion, .. } => vec![suggestion.clone()],
316 Self::Unknown { suggestion, .. } => vec![suggestion.clone()],
317 Self::Compilation { suggestion, .. } => vec![suggestion.clone()],
318 Self::Io { suggestion, .. } => vec![suggestion.clone()],
319 Self::SerializationError { suggestion, .. } => vec![suggestion.clone()],
320 Self::DeserializationError { suggestion, .. } => vec![suggestion.clone()],
321 Self::CompressionError { suggestion, .. } => vec![suggestion.clone()],
322 Self::DecompressionError { suggestion, .. } => vec![suggestion.clone()],
323 Self::FeatureError { message, .. } => vec![message.clone()],
324 }
325 }
326 pub fn is_recoverable(&self) -> bool {
327 match self {
328 Self::ConfigConversion { .. } => true,
329 Self::DatasetProcessing { .. } => true,
330 Self::QualityValidation { score, .. } => *score > 0.3,
331 Self::FormatConversion { .. } => true,
332 Self::UnsupportedAlgorithm { .. } => false,
333 Self::DatasetNotFound { .. } => false,
334 Self::HlxProcessing { .. } => true,
335 Self::ForgeIntegration { .. } => true,
336 Self::ConfigValidation { .. } => true,
337 Self::InvalidInput { .. } => true,
338 Self::ExecutionError { .. } => true,
339 Self::InvalidParameters { .. } => true,
340 Self::UnknownOperator { .. } => true,
341 Self::ValidationError { .. } => true,
342 Self::HashError { .. } => true,
343 Self::JsonError { .. } => true,
344 Self::Base64Error { .. } => true,
345 Self::Unknown { .. } => true,
346 Self::Compilation { .. } => true,
347 Self::Io { .. } => true,
348 Self::SerializationError { .. } => true,
349 Self::DeserializationError { .. } => true,
350 Self::CompressionError { .. } => true,
351 Self::DecompressionError { .. } => true,
352 Self::FeatureError { .. } => false,
353 }
354 }
355}
356impl From<std::io::Error> for HlxError {
357 fn from(err: std::io::Error) -> Self {
358 Self::io_error(err.to_string(), "Check file permissions and paths")
359 }
360}
361impl From<serde_json::Error> for HlxError {
362 fn from(err: serde_json::Error) -> Self {
363 Self::json_error(err.to_string(), "Check JSON format and structure")
364 }
365}
366#[derive(Debug)]
367pub struct LexerError {
368 pub message: String,
369 pub location: SourceLocation,
370 pub source_line: String,
371 pub suggestion: Option<String>,
372}
373#[derive(Debug)]
374pub struct ParserError {
375 pub message: String,
376 pub location: SourceLocation,
377 pub expected: Vec<String>,
378 pub found: String,
379 pub source_line: String,
380 pub suggestion: Option<String>,
381}
382#[derive(Debug)]
383pub struct SemanticError {
384 pub kind: SemanticErrorKind,
385 pub location: SourceLocation,
386 pub entity: String,
387 pub context: Vec<String>,
388}
389#[derive(Debug)]
390pub enum SemanticErrorKind {
391 UndefinedReference,
392 DuplicateDefinition,
393 TypeMismatch { expected: String, found: String },
394 CircularDependency,
395 InvalidValue,
396 MissingRequired,
397 DeprecatedFeature,
398}
399#[derive(Debug)]
400pub struct CompilationError {
401 pub stage: CompilationStage,
402 pub message: String,
403 pub file: Option<PathBuf>,
404 pub recoverable: bool,
405}
406#[derive(Debug)]
407pub enum CompilationStage {
408 Parsing,
409 Validation,
410 Optimization,
411 CodeGeneration,
412 Serialization,
413 Bundling,
414}
415#[derive(Debug)]
416pub struct RuntimeError {
417 pub kind: RuntimeErrorKind,
418 pub message: String,
419 pub stack_trace: Vec<String>,
420}
421#[derive(Debug, PartialEq)]
422pub enum RuntimeErrorKind {
423 InvalidInstruction,
424 StackUnderflow,
425 StackOverflow,
426 MemoryAccessViolation,
427 DivisionByZero,
428 TypeConversion,
429 ResourceNotFound,
430}
431#[derive(Debug)]
432pub struct IoError {
433 pub operation: IoOperation,
434 pub path: PathBuf,
435 pub message: String,
436}
437#[derive(Debug)]
438pub enum IoOperation {
439 Read,
440 Write,
441 Create,
442 Delete,
443 Rename,
444 Metadata,
445}
446impl fmt::Display for LexerError {
447 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
448 writeln!(f, "Lexer error at {}:{}", self.location.line, self.location.column)?;
449 writeln!(f, " {}", self.message)?;
450 writeln!(f, " {}", self.source_line)?;
451 writeln!(f, " {}^", " ".repeat(self.location.column))?;
452 if let Some(suggestion) = &self.suggestion {
453 writeln!(f, " Suggestion: {}", suggestion)?;
454 }
455 Ok(())
456 }
457}
458impl fmt::Display for ParserError {
459 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
460 writeln!(f, "Parser error at {}:{}", self.location.line, self.location.column)?;
461 writeln!(f, " {}", self.message)?;
462 writeln!(f, " {}", self.source_line)?;
463 writeln!(f, " {}^", " ".repeat(self.location.column))?;
464 if !self.expected.is_empty() {
465 writeln!(f, " Expected: {}", self.expected.join(" | "))?;
466 }
467 writeln!(f, " Found: {}", self.found)?;
468 if let Some(suggestion) = &self.suggestion {
469 writeln!(f, " Suggestion: {}", suggestion)?;
470 }
471 Ok(())
472 }
473}
474impl fmt::Display for SemanticError {
475 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
476 write!(f, "Semantic error: ")?;
477 match &self.kind {
478 SemanticErrorKind::UndefinedReference => {
479 writeln!(f, "Undefined reference to '{}'", self.entity)?;
480 }
481 SemanticErrorKind::DuplicateDefinition => {
482 writeln!(f, "Duplicate definition of '{}'", self.entity)?;
483 }
484 SemanticErrorKind::TypeMismatch { expected, found } => {
485 writeln!(
486 f, "Type mismatch for '{}': expected {}, found {}", self.entity,
487 expected, found
488 )?;
489 }
490 SemanticErrorKind::CircularDependency => {
491 writeln!(f, "Circular dependency involving '{}'", self.entity)?;
492 }
493 SemanticErrorKind::InvalidValue => {
494 writeln!(f, "Invalid value for '{}'", self.entity)?;
495 }
496 SemanticErrorKind::MissingRequired => {
497 writeln!(f, "Missing required field '{}'", self.entity)?;
498 }
499 SemanticErrorKind::DeprecatedFeature => {
500 writeln!(f, "Use of deprecated feature '{}'", self.entity)?;
501 }
502 }
503 writeln!(f, " at {}:{}", self.location.line, self.location.column)?;
504 if !self.context.is_empty() {
505 writeln!(f, " Context:")?;
506 for ctx in &self.context {
507 writeln!(f, " - {}", ctx)?;
508 }
509 }
510 Ok(())
511 }
512}
513impl fmt::Display for CompilationError {
514 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
515 write!(f, "Compilation error during {:?}: {}", self.stage, self.message)?;
516 if let Some(file) = &self.file {
517 write!(f, " in file {:?}", file)?;
518 }
519 if self.recoverable {
520 write!(f, " (recoverable)")?;
521 }
522 Ok(())
523 }
524}
525impl fmt::Display for RuntimeError {
526 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
527 writeln!(f, "Runtime error: {:?}", self.kind)?;
528 writeln!(f, " {}", self.message)?;
529 if !self.stack_trace.is_empty() {
530 writeln!(f, " Stack trace:")?;
531 for frame in &self.stack_trace {
532 writeln!(f, " {}", frame)?;
533 }
534 }
535 Ok(())
536 }
537}
538impl fmt::Display for IoError {
539 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
540 write!(
541 f, "IO error during {:?} operation on {:?}: {}", self.operation, self.path,
542 self.message
543 )
544 }
545}
546impl std::error::Error for LexerError {}
547impl std::error::Error for ParserError {}
548impl std::error::Error for SemanticError {}
549impl std::error::Error for CompilationError {}
550impl std::error::Error for RuntimeError {}
551impl std::error::Error for IoError {}
552pub type Result<T> = std::result::Result<T, HlxError>;
553pub type HlxResult<T> = std::result::Result<T, HlxError>;
554pub struct ErrorRecovery;
555impl ErrorRecovery {
556 pub fn suggest_for_undefined_reference(name: &str) -> Option<String> {
557 if name == "agnet" {
558 return Some("Did you mean 'agent'?".to_string());
559 }
560 if name == "worfklow" || name == "workfow" {
561 return Some("Did you mean 'workflow'?".to_string());
562 }
563 None
564 }
565 pub fn suggest_for_syntax_error(found: &str, expected: &[String]) -> Option<String> {
566 if expected.contains(&"=".to_string()) && found == ":" {
567 return Some("Use '=' for assignment, not ':'".to_string());
568 }
569 if expected.contains(&"{".to_string()) && found == "(" {
570 return Some("Use '{' for block start, not '('".to_string());
571 }
572 None
573 }
574}