Skip to main content

horizon_lattice_core/
error.rs

1//! Error types for Horizon Lattice.
2
3use std::fmt;
4
5use crate::object::ObjectError;
6use crate::property::PropertyError;
7
8/// The main error type for Horizon Lattice operations.
9#[derive(Debug)]
10pub enum LatticeError {
11    /// Application has already been initialized.
12    ApplicationAlreadyInitialized,
13    /// Application has not been initialized yet.
14    ApplicationNotInitialized,
15    /// Failed to create the event loop.
16    EventLoopCreation(String),
17    /// Failed to create a window.
18    WindowCreation(String),
19    /// Timer-related error.
20    Timer(TimerError),
21    /// Scheduler-related error.
22    Scheduler(SchedulerError),
23    /// Object-related error.
24    Object(ObjectError),
25    /// Property-related error.
26    Property(PropertyError),
27    /// Signal-related error.
28    Signal(SignalError),
29    /// Thread pool-related error.
30    ThreadPool(ThreadPoolError),
31    /// The event loop has already exited.
32    EventLoopExited,
33}
34
35impl fmt::Display for LatticeError {
36    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37        match self {
38            Self::ApplicationAlreadyInitialized => {
39                write!(f, "Application has already been initialized")
40            }
41            Self::ApplicationNotInitialized => {
42                write!(
43                    f,
44                    "Application has not been initialized. Call Application::new() first"
45                )
46            }
47            Self::EventLoopCreation(msg) => {
48                write!(f, "Failed to create event loop: {msg}")
49            }
50            Self::WindowCreation(msg) => {
51                write!(f, "Failed to create window: {msg}")
52            }
53            Self::Timer(err) => write!(f, "Timer error: {err}"),
54            Self::Scheduler(err) => write!(f, "Scheduler error: {err}"),
55            Self::Object(err) => write!(f, "Object error: {err}"),
56            Self::Property(err) => write!(f, "Property error: {err}"),
57            Self::Signal(err) => write!(f, "Signal error: {err}"),
58            Self::ThreadPool(err) => write!(f, "Thread pool error: {err}"),
59            Self::EventLoopExited => {
60                write!(f, "The event loop has already exited")
61            }
62        }
63    }
64}
65
66impl std::error::Error for LatticeError {
67    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
68        match self {
69            Self::Timer(err) => Some(err),
70            Self::Scheduler(err) => Some(err),
71            Self::Object(err) => Some(err),
72            Self::Property(err) => Some(err),
73            Self::Signal(err) => Some(err),
74            Self::ThreadPool(err) => Some(err),
75            _ => None,
76        }
77    }
78}
79
80/// Timer-specific errors.
81#[derive(Debug)]
82pub enum TimerError {
83    /// The timer ID is invalid or has already been removed.
84    InvalidTimerId,
85    /// Failed to send timer event to the event loop.
86    EventDispatchFailed,
87}
88
89impl fmt::Display for TimerError {
90    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91        match self {
92            Self::InvalidTimerId => write!(f, "Invalid or expired timer ID"),
93            Self::EventDispatchFailed => write!(f, "Failed to dispatch timer event"),
94        }
95    }
96}
97
98impl std::error::Error for TimerError {}
99
100impl From<TimerError> for LatticeError {
101    fn from(err: TimerError) -> Self {
102        Self::Timer(err)
103    }
104}
105
106/// Scheduler-specific errors.
107#[derive(Debug)]
108pub enum SchedulerError {
109    /// The scheduled task ID is invalid or has already been removed.
110    InvalidTaskId,
111    /// Failed to send scheduler event to the event loop.
112    EventDispatchFailed,
113}
114
115impl fmt::Display for SchedulerError {
116    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117        match self {
118            Self::InvalidTaskId => write!(f, "Invalid or expired scheduled task ID"),
119            Self::EventDispatchFailed => write!(f, "Failed to dispatch scheduler event"),
120        }
121    }
122}
123
124impl std::error::Error for SchedulerError {}
125
126impl From<SchedulerError> for LatticeError {
127    fn from(err: SchedulerError) -> Self {
128        Self::Scheduler(err)
129    }
130}
131
132impl From<ObjectError> for LatticeError {
133    fn from(err: ObjectError) -> Self {
134        Self::Object(err)
135    }
136}
137
138impl From<PropertyError> for LatticeError {
139    fn from(err: PropertyError) -> Self {
140        Self::Property(err)
141    }
142}
143
144impl From<SignalError> for LatticeError {
145    fn from(err: SignalError) -> Self {
146        Self::Signal(err)
147    }
148}
149
150/// Signal-specific errors.
151#[derive(Debug, Clone, PartialEq, Eq)]
152pub enum SignalError {
153    /// The connection ID is invalid or has already been disconnected.
154    InvalidConnection,
155    /// The signal has been dropped and is no longer available.
156    SignalDropped,
157    /// Failed to queue the signal invocation to the event loop.
158    QueueFailed,
159}
160
161impl fmt::Display for SignalError {
162    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
163        match self {
164            Self::InvalidConnection => write!(f, "Invalid or disconnected connection ID"),
165            Self::SignalDropped => write!(f, "Signal has been dropped"),
166            Self::QueueFailed => write!(f, "Failed to queue signal invocation"),
167        }
168    }
169}
170
171impl std::error::Error for SignalError {}
172
173/// Thread pool-specific errors.
174#[derive(Debug)]
175pub enum ThreadPoolError {
176    /// The thread pool has already been initialized.
177    AlreadyInitialized,
178    /// Failed to create the thread pool.
179    CreationFailed(String),
180    /// Task was cancelled.
181    TaskCancelled,
182    /// Failed to submit task to the pool.
183    SubmissionFailed,
184}
185
186/// Thread safety-specific errors.
187#[derive(Debug, Clone)]
188pub enum ThreadError {
189    /// Operation was called from the wrong thread.
190    WrongThread {
191        /// Description of the operation that failed.
192        operation: String,
193        /// The expected thread (if known).
194        expected: Option<String>,
195        /// The actual thread name/id.
196        actual: String,
197    },
198    /// Object was accessed from a thread other than its owning thread.
199    AffinityViolation {
200        /// Description of the object.
201        object: String,
202    },
203}
204
205impl fmt::Display for ThreadError {
206    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207        match self {
208            Self::WrongThread {
209                operation,
210                expected,
211                actual,
212            } => {
213                write!(f, "'{operation}' called from wrong thread (got: {actual}")?;
214                if let Some(exp) = expected {
215                    write!(f, ", expected: {exp}")?;
216                }
217                write!(f, ")")
218            }
219            Self::AffinityViolation { object } => {
220                write!(
221                    f,
222                    "'{object}' accessed from wrong thread (thread affinity violation)"
223                )
224            }
225        }
226    }
227}
228
229impl std::error::Error for ThreadError {}
230
231impl fmt::Display for ThreadPoolError {
232    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
233        match self {
234            Self::AlreadyInitialized => write!(f, "Thread pool has already been initialized"),
235            Self::CreationFailed(msg) => write!(f, "Failed to create thread pool: {msg}"),
236            Self::TaskCancelled => write!(f, "Task was cancelled"),
237            Self::SubmissionFailed => write!(f, "Failed to submit task to thread pool"),
238        }
239    }
240}
241
242impl std::error::Error for ThreadPoolError {}
243
244impl From<ThreadPoolError> for LatticeError {
245    fn from(err: ThreadPoolError) -> Self {
246        Self::ThreadPool(err)
247    }
248}
249
250/// A specialized Result type for Horizon Lattice operations.
251pub type Result<T> = std::result::Result<T, LatticeError>;