Mountain/Error/
CoreError.rs

1//! # Core Error Types
2//!
3//! Provides the base error types and traits used across Mountain.
4//! All Mountain errors should implement or use these core types.
5
6use std::{error::Error as StdError, fmt};
7
8use serde::{Deserialize, Serialize};
9
10/// Severity level of an error
11#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
12pub enum ErrorSeverity {
13	/// Informational, can be ignored
14	Info = 0,
15	/// Warning, might indicate a problem
16	Warning = 1,
17	/// Error, operation failed
18	Error = 2,
19	/// Critical, system may be unstable
20	Critical = 3,
21}
22
23impl fmt::Display for ErrorSeverity {
24	fn fmt(&self, f:&mut fmt::Formatter<'_>) -> fmt::Result {
25		match self {
26			ErrorSeverity::Info => write!(f, "Info"),
27			ErrorSeverity::Warning => write!(f, "Warning"),
28			ErrorSeverity::Error => write!(f, "Error"),
29			ErrorSeverity::Critical => write!(f, "Critical"),
30		}
31	}
32}
33
34/// Category of error
35#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
36pub enum ErrorKind {
37	/// IPC communication error
38	IPC,
39	/// File system error
40	FileSystem,
41	/// Configuration error
42	Configuration,
43	/// Service error
44	Service,
45	/// Provider error
46	Provider,
47	/// Generic/unknown error
48	Other,
49}
50
51impl fmt::Display for ErrorKind {
52	fn fmt(&self, f:&mut fmt::Formatter<'_>) -> fmt::Result {
53		match self {
54			ErrorKind::IPC => write!(f, "IPC"),
55			ErrorKind::FileSystem => write!(f, "FileSystem"),
56			ErrorKind::Configuration => write!(f, "Configuration"),
57			ErrorKind::Service => write!(f, "Service"),
58			ErrorKind::Provider => write!(f, "Provider"),
59			ErrorKind::Other => write!(f, "Other"),
60		}
61	}
62}
63
64/// Error context providing additional information
65#[derive(Debug, Clone, Serialize, Deserialize)]
66pub struct ErrorContext {
67	/// Human-readable error message
68	pub message:String,
69	/// Error kind
70	pub kind:ErrorKind,
71	/// Severity level
72	pub severity:ErrorSeverity,
73	/// Optional operation that caused the error
74	pub operation:Option<String>,
75	/// Optional component where the error occurred
76	pub component:Option<String>,
77}
78
79impl ErrorContext {
80	/// Create a new error context
81	pub fn new(message:impl Into<String>) -> Self {
82		Self {
83			message:message.into(),
84			kind:ErrorKind::Other,
85			severity:ErrorSeverity::Error,
86			operation:None,
87			component:None,
88		}
89	}
90
91	/// Set the error kind
92	pub fn with_kind(mut self, kind:ErrorKind) -> Self {
93		self.kind = kind;
94		self
95	}
96
97	/// Set the severity level
98	pub fn with_severity(mut self, severity:ErrorSeverity) -> Self {
99		self.severity = severity;
100		self
101	}
102
103	/// Set the operation
104	pub fn with_operation(mut self, operation:impl Into<String>) -> Self {
105		self.operation = Some(operation.into());
106		self
107	}
108
109	/// Set the component
110	pub fn with_component(mut self, component:impl Into<String>) -> Self {
111		self.component = Some(component.into());
112		self
113	}
114}
115
116impl fmt::Display for ErrorContext {
117	fn fmt(&self, f:&mut fmt::Formatter<'_>) -> fmt::Result {
118		write!(f, "[{}][{}] {}", self.kind, self.severity, self.message)
119	}
120}
121
122/// Base Mountain error type
123#[derive(Debug, Clone, Serialize, Deserialize)]
124pub struct MountainError {
125	/// Error context
126	pub context:ErrorContext,
127	/// Optional source error (simplified for serialization)
128	pub source:Option<String>,
129	/// Optional stack trace
130	pub stack_trace:Option<String>,
131}
132
133impl MountainError {
134	/// Create a new Mountain error
135	pub fn new(context:ErrorContext) -> Self { Self { context, source:None, stack_trace:None } }
136
137	/// Create an error with a source
138	pub fn with_source(mut self, source:impl Into<String>) -> Self {
139		self.source = Some(source.into());
140		self
141	}
142
143	/// Create an error with a stack trace
144	pub fn with_stack_trace(mut self, stack_trace:impl Into<String>) -> Self {
145		self.stack_trace = Some(stack_trace.into());
146		self
147	}
148
149	/// Get the error message
150	pub fn message(&self) -> &str { &self.context.message }
151
152	/// Get the error kind
153	pub fn kind(&self) -> ErrorKind { self.context.kind }
154
155	/// Get the error severity
156	pub fn severity(&self) -> ErrorSeverity { self.context.severity }
157
158	/// Check if error is critical
159	pub fn is_critical(&self) -> bool { self.context.severity == ErrorSeverity::Critical }
160}
161
162impl fmt::Display for MountainError {
163	fn fmt(&self, f:&mut fmt::Formatter<'_>) -> fmt::Result {
164		write!(f, "{}", self.context)?;
165		if let Some(source) = &self.source {
166			write!(f, " ({})", source)?;
167		}
168		Ok(())
169	}
170}
171
172impl StdError for MountainError {}
173
174impl From<ErrorContext> for MountainError {
175	fn from(context:ErrorContext) -> Self { Self::new(context) }
176}
177
178/// Result type alias for Mountain operations
179pub type Result<T> = std::result::Result<T, MountainError>;