tramex_tools/
errors.rs

1//! Error handling for Tramex Tools
2
3#[derive(serde::Deserialize, Debug, Clone)]
4/// Error codes for Tramex Tools
5pub enum ErrorCode {
6    /// Not set
7    NotSet = 0,
8
9    /// WebSocket: Failed to connect
10    WebSocketFailedToConnect,
11
12    /// WebSocket: Error encoding message
13    WebSocketErrorEncodingMessage,
14
15    /// WebSocket: Error decoding message
16    WebSocketErrorDecodingMessage,
17
18    /// WebSocket: Unknown message received
19    WebSocketUnknownMessageReceived,
20
21    /// WebSocket: Unknown binary message received
22    WebSocketUnknownBinaryMessageReceived,
23
24    /// WebSocket: Error
25    WebSocketError,
26
27    /// WebSocket: Closed
28    WebSocketClosed,
29
30    /// WebSocket: Error closing
31    WebSocketErrorClosing,
32
33    /// File: No file selected
34    FileNotSelected,
35
36    /// File: Error reading file
37    FileErrorReadingFile,
38
39    /// File: Not ready
40    FileNotReady,
41
42    /// File: Invalid encoding (wrong UTF-8)
43    FileInvalidEncoding,
44
45    /// Hexe decoding failed
46    HexeDecodingError,
47
48    /// File : End of the file
49    EndOfFile,
50
51    /// File: Error while parsing the file
52    FileParsing,
53
54    /// Request error
55    RequestError,
56
57    /// ParsingLayerNotImplemented
58    ParsingLayerNotImplemented,
59}
60
61impl Default for ErrorCode {
62    fn default() -> Self {
63        Self::NotSet
64    }
65}
66
67impl std::fmt::Display for ErrorCode {
68    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69        // use to_string() to get the string representation of the error code
70        let str = match self {
71            Self::WebSocketFailedToConnect => "WebSocket: Failed to connect",
72            Self::WebSocketErrorEncodingMessage => "WebSocket: Error encoding message",
73            Self::WebSocketErrorDecodingMessage => "WebSocket: Error decoding message",
74            Self::WebSocketUnknownMessageReceived => "WebSocket: Unknown message received",
75            Self::WebSocketUnknownBinaryMessageReceived => "WebSocket: Unknown binary message received",
76            Self::WebSocketError => "WebSocket: Error",
77            Self::WebSocketClosed => "WebSocket: Closed",
78            Self::WebSocketErrorClosing => "WebSocket: Error closing",
79            Self::FileNotSelected => "File: No file selected",
80            Self::FileErrorReadingFile => "File: Error reading file",
81            Self::FileNotReady => "File: Not ready",
82            Self::FileInvalidEncoding => "File: Invalid encoding (wrong UTF-8)",
83            Self::NotSet => "Error code not set, please create an issue",
84            Self::HexeDecodingError => "Hexe decoding error",
85            Self::EndOfFile => "End of File",
86            Self::FileParsing => "File: Parsing error",
87            Self::RequestError => "Request error",
88            Self::ParsingLayerNotImplemented => "Parsing layer not implemented",
89        };
90        write!(f, "{str}")
91    }
92}
93
94impl ErrorCode {
95    /// Check if the error is recoverable
96    pub fn is_recoverable(&self) -> bool {
97        !matches!(self, Self::FileInvalidEncoding | Self::WebSocketClosed)
98    }
99}
100
101#[derive(serde::Deserialize, Debug, Default, Clone)]
102/// Error structure for Tramex Tools
103pub struct TramexError {
104    /// Error message (human readable)
105    pub message: String,
106
107    /// Debug information
108    pub debug: String,
109
110    /// Error code
111    code: ErrorCode,
112}
113
114impl TramexError {
115    /// Create a new error
116    pub fn new(message: String, code: ErrorCode) -> Self {
117        log::debug!("Error: {} - {}\n{}", code, message, std::backtrace::Backtrace::capture());
118        Self {
119            message,
120            code,
121            debug: String::new(),
122        }
123    }
124
125    /// Create a new error
126    pub fn new_with_line(message: String, code: ErrorCode, debug: String) -> Self {
127        Self { message, code, debug }
128    }
129
130    /// Check if the error is recoverable
131    pub fn is_recoverable(&self) -> bool {
132        self.code.is_recoverable()
133    }
134
135    /// Get the error message
136    pub fn get_msg(&self) -> String {
137        format!("[{}] {}", self.code, self.message)
138    }
139
140    /// Get the error code
141    pub fn get_code(&self) -> ErrorCode {
142        self.code.clone()
143    }
144}
145
146/// Macro to get the file and line number
147#[macro_export]
148macro_rules! tramex_error {
149    ($msg:expr, $code:expr) => {
150        TramexError::new_with_line($msg, $code, format!("{}:{}", file!(), line!()))
151    };
152}