Skip to main content

Mountain/Error/
ProviderError.rs

1//! # Provider Error Types
2//!
3//! Provider-specific error types for Mountain.
4//! Covers provider registration, initialization, method dispatch,
5//! configuration validation, operation timeout, and availability
6//! for capability providers such as `DocumentProvider` and
7//! `FileSystemProvider`.
8
9use std::{error::Error as StdError, fmt};
10
11use serde::{Deserialize, Serialize};
12
13use super::CoreError::{ErrorContext, ErrorKind, ErrorSeverity, MountainError};
14
15/// Provider operation error types.
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub enum ProviderError {
18	/// Provider not registered.
19	ProviderNotRegistered { context:ErrorContext, provider_name:String },
20
21	/// Provider initialization failed.
22	InitializationFailed { context:ErrorContext, provider_name:String, source:Option<String> },
23
24	/// Provider method not implemented.
25	MethodNotImplemented { context:ErrorContext, provider_name:String, method_name:String },
26
27	/// Invalid provider configuration.
28	InvalidConfiguration { context:ErrorContext, provider_name:String, errors:Vec<String> },
29
30	/// Provider timeout.
31	Timeout { context:ErrorContext, provider_name:String, operation:String, timeout_ms:u64 },
32
33	/// Provider unavailable.
34	Unavailable { context:ErrorContext, provider_name:String, reason:String },
35}
36
37impl ProviderError {
38	/// Get the error context.
39	pub fn context(&self) -> &ErrorContext {
40		match self {
41			ProviderError::ProviderNotRegistered { context, .. } => context,
42
43			ProviderError::InitializationFailed { context, .. } => context,
44
45			ProviderError::MethodNotImplemented { context, .. } => context,
46
47			ProviderError::InvalidConfiguration { context, .. } => context,
48
49			ProviderError::Timeout { context, .. } => context,
50
51			ProviderError::Unavailable { context, .. } => context,
52		}
53	}
54
55	/// Create a provider not registered error.
56	pub fn provider_not_registered(provider_name:impl Into<String>) -> Self {
57		let provider_name_str = provider_name.into();
58
59		Self::ProviderNotRegistered {
60			context:ErrorContext::new(format!("Provider not registered: {}", provider_name_str))
61				.with_kind(ErrorKind::Provider)
62				.with_severity(ErrorSeverity::Error),
63
64			provider_name:provider_name_str,
65		}
66	}
67
68	/// Create an initialization failed error.
69	pub fn initialization_failed(provider_name:impl Into<String>, source:Option<String>) -> Self {
70		let provider_name_str = provider_name.into();
71
72		Self::InitializationFailed {
73			context:ErrorContext::new(format!("Provider initialization failed: {}", provider_name_str))
74				.with_kind(ErrorKind::Provider)
75				.with_severity(ErrorSeverity::Critical),
76
77			provider_name:provider_name_str,
78
79			source,
80		}
81	}
82
83	/// Create a method not implemented error.
84	pub fn method_not_implemented(provider_name:impl Into<String>, method_name:impl Into<String>) -> Self {
85		let provider_name_str = provider_name.into();
86
87		let method_name_str = method_name.into();
88
89		Self::MethodNotImplemented {
90			context:ErrorContext::new(format!(
91				"Method '{}' not implemented in provider '{}'",
92				method_name_str, provider_name_str
93			))
94			.with_kind(ErrorKind::Provider)
95			.with_severity(ErrorSeverity::Error),
96
97			provider_name:provider_name_str,
98
99			method_name:method_name_str,
100		}
101	}
102
103	/// Create an invalid configuration error.
104	pub fn invalid_configuration(provider_name:impl Into<String>, errors:Vec<String>) -> Self {
105		let provider_name_str = provider_name.into();
106
107		Self::InvalidConfiguration {
108			context:ErrorContext::new(format!(
109				"Provider '{}' has invalid configuration: {} error(s)",
110				provider_name_str,
111				errors.len()
112			))
113			.with_kind(ErrorKind::Provider)
114			.with_severity(ErrorSeverity::Error),
115
116			provider_name:provider_name_str,
117
118			errors,
119		}
120	}
121
122	/// Create a timeout error.
123	pub fn timeout(provider_name:impl Into<String>, operation:impl Into<String>, timeout_ms:u64) -> Self {
124		let provider_name_str = provider_name.into();
125
126		let operation_str = operation.into();
127
128		Self::Timeout {
129			context:ErrorContext::new(format!(
130				"Provider timeout: {} operation timed out after {}ms",
131				provider_name_str, timeout_ms
132			))
133			.with_kind(ErrorKind::Provider)
134			.with_severity(ErrorSeverity::Error)
135			.with_operation(operation_str.clone()),
136
137			provider_name:provider_name_str,
138
139			operation:operation_str,
140
141			timeout_ms,
142		}
143	}
144
145	/// Create an unavailable error.
146	pub fn unavailable(provider_name:impl Into<String>, reason:impl Into<String>) -> Self {
147		let provider_name_str = provider_name.into();
148
149		let reason_str = reason.into();
150
151		Self::Unavailable {
152			context:ErrorContext::new(format!("Provider '{}' unavailable: {}", provider_name_str, reason_str))
153				.with_kind(ErrorKind::Provider)
154				.with_severity(ErrorSeverity::Error),
155
156			provider_name:provider_name_str,
157
158			reason:reason_str,
159		}
160	}
161}
162
163impl fmt::Display for ProviderError {
164	fn fmt(&self, f:&mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.context()) }
165}
166
167impl StdError for ProviderError {}
168
169impl From<ProviderError> for MountainError {
170	fn from(err:ProviderError) -> Self { MountainError::new(err.context().clone()).with_source(err.to_string()) }
171}