Skip to main content

telarex_core/errors/
mod.rs

1//! Error framework — typed errors with codes, severity levels, and user-facing solutions.
2//!
3//! [`TrexError`] is the primary error type, carrying a code (e.g. `TRX-F01`),
4//! a severity [`ErrorLevel`], a human-readable message, and a suggested solution.
5//! Factory methods like [`file_not_found`](TrexError::file_not_found) and
6//! [`network_failure`](TrexError::network_failure) provide convenient construction.
7
8use serde::{Deserialize, Serialize};
9use thiserror::Error;
10
11/// Severity level for an error or log message.
12#[derive(Debug, Clone, Serialize, Deserialize, Error)]
13pub enum ErrorLevel {
14    #[error("INFO")]
15    Info,
16    #[error("WARN")]
17    Warning,
18    #[error("ERROR")]
19    Error,
20    #[error("FATAL")]
21    Fatal,
22}
23
24/// A typed error with a unique code, severity level, message, and suggested solution.
25#[derive(Debug, Clone, Serialize, Deserialize, Error)]
26#[error("[{code}] {level}: {message}")]
27pub struct TrexError {
28    pub code: String,
29    pub level: ErrorLevel,
30    pub message: String,
31    pub solution: String,
32}
33
34impl TrexError {
35    /// Construct a [`TrexError`] from its raw fields.
36    pub fn new(code: &str, level: ErrorLevel, message: &str, solution: &str) -> Self {
37        Self {
38            code: code.to_string(),
39            level,
40            message: message.to_string(),
41            solution: solution.to_string(),
42        }
43    }
44
45    /// Create an error for a missing file (code `TRX-F01`).
46    pub fn file_not_found(path: &str) -> Self {
47        Self::new("TRX-F01", ErrorLevel::Error, &format!("File not found: {}", path), "Check the path and permissions.")
48    }
49
50    /// Create an error for a network failure (code `TRX-N01`).
51    pub fn network_failure(details: &str) -> Self {
52        Self::new("TRX-N01", ErrorLevel::Warning, &format!("Network error: {}", details), "Check your internet connection or bootstrap nodes.")
53    }
54
55    /// Create an error for a failed ZK-authentication (code `TRX-A01`).
56    pub fn auth_failed() -> Self {
57        Self::new("TRX-A01", ErrorLevel::Error, "ZK-Authentication failed.", "Ensure you have the correct Lodge Key.")
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use super::*;
64
65    #[test]
66    fn test_error_level_display() {
67        assert_eq!(ErrorLevel::Info.to_string(), "INFO");
68        assert_eq!(ErrorLevel::Warning.to_string(), "WARN");
69        assert_eq!(ErrorLevel::Error.to_string(), "ERROR");
70        assert_eq!(ErrorLevel::Fatal.to_string(), "FATAL");
71    }
72
73    #[test]
74    fn test_trex_error_format() {
75        let err = TrexError::file_not_found("/path/to/file.rs");
76        let msg = err.to_string();
77        assert!(msg.contains("TRX-F01"));
78        assert!(msg.contains("ERROR"));
79        assert!(msg.contains("File not found"));
80    }
81
82    #[test]
83    fn test_file_not_found() {
84        let err = TrexError::file_not_found("test.txt");
85        assert_eq!(err.code, "TRX-F01");
86        assert_eq!(err.level.to_string(), "ERROR");
87    }
88
89    #[test]
90    fn test_network_failure() {
91        let err = TrexError::network_failure("timeout");
92        assert_eq!(err.code, "TRX-N01");
93        assert_eq!(err.level.to_string(), "WARN");
94    }
95
96    #[test]
97    fn test_auth_failed() {
98        let err = TrexError::auth_failed();
99        assert_eq!(err.code, "TRX-A01");
100        assert_eq!(err.level.to_string(), "ERROR");
101        assert_eq!(err.message, "ZK-Authentication failed.");
102    }
103}