Mountain/Error/
ProviderError.rs

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