Mountain/Error/
ServiceError.rs1use std::{error::Error as StdError, fmt};
7
8use serde::{Deserialize, Serialize};
9
10use super::CoreError::{ErrorContext, ErrorKind, ErrorSeverity, MountainError, Result};
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
14pub enum ServiceError {
15 ServiceNotFound { context:ErrorContext, service_name:String },
17 InitializationFailed { context:ErrorContext, service_name:String, source:Option<String> },
19 AlreadyRunning { context:ErrorContext, service_name:String },
21 NotRunning { context:ErrorContext, service_name:String },
23 StartFailed { context:ErrorContext, service_name:String, source:Option<String> },
25 StopFailed { context:ErrorContext, service_name:String, source:Option<String> },
27 Timeout { context:ErrorContext, service_name:String, operation:String, timeout_ms:u64 },
29 DependencyError { context:ErrorContext, service_name:String, dependency:String },
31}
32
33impl ServiceError {
34 pub fn context(&self) -> &ErrorContext {
36 match self {
37 ServiceError::ServiceNotFound { context, .. } => context,
38 ServiceError::InitializationFailed { context, .. } => context,
39 ServiceError::AlreadyRunning { context, .. } => context,
40 ServiceError::NotRunning { context, .. } => context,
41 ServiceError::StartFailed { context, .. } => context,
42 ServiceError::StopFailed { context, .. } => context,
43 ServiceError::Timeout { context, .. } => context,
44 ServiceError::DependencyError { context, .. } => context,
45 }
46 }
47
48 pub fn service_not_found(service_name:impl Into<String>) -> Self {
50 let service_name_str = service_name.into();
51 Self::ServiceNotFound {
52 context:ErrorContext::new(format!("Service not found: {}", service_name_str))
53 .with_kind(ErrorKind::Service)
54 .with_severity(ErrorSeverity::Error),
55 service_name:service_name_str,
56 }
57 }
58
59 pub fn initialization_failed(service_name:impl Into<String>, source:Option<String>) -> Self {
61 let service_name_str = service_name.into();
62 Self::InitializationFailed {
63 context:ErrorContext::new(format!("Service initialization failed: {}", service_name_str))
64 .with_kind(ErrorKind::Service)
65 .with_severity(ErrorSeverity::Critical),
66 service_name:service_name_str,
67 source,
68 }
69 }
70
71 pub fn already_running(service_name:impl Into<String>) -> Self {
73 let service_name_str = service_name.into();
74 Self::AlreadyRunning {
75 context:ErrorContext::new(format!("Service already running: {}", service_name_str))
76 .with_kind(ErrorKind::Service)
77 .with_severity(ErrorSeverity::Warning),
78 service_name:service_name_str,
79 }
80 }
81
82 pub fn not_running(service_name:impl Into<String>) -> Self {
84 let service_name_str = service_name.into();
85 Self::NotRunning {
86 context:ErrorContext::new(format!("Service not running: {}", service_name_str))
87 .with_kind(ErrorKind::Service)
88 .with_severity(ErrorSeverity::Error),
89 service_name:service_name_str,
90 }
91 }
92
93 pub fn start_failed(service_name:impl Into<String>, source:Option<String>) -> Self {
95 let service_name_str = service_name.into();
96 Self::StartFailed {
97 context:ErrorContext::new(format!("Service start failed: {}", service_name_str))
98 .with_kind(ErrorKind::Service)
99 .with_severity(ErrorSeverity::Error),
100 service_name:service_name_str,
101 source,
102 }
103 }
104
105 pub fn timeout(service_name:impl Into<String>, operation:impl Into<String>, timeout_ms:u64) -> Self {
107 let service_name_str = service_name.into();
108 let operation_str = operation.into();
109 Self::Timeout {
110 context:ErrorContext::new(format!(
111 "Service timeout: {} operation timed out after {}ms",
112 service_name_str, timeout_ms
113 ))
114 .with_kind(ErrorKind::Service)
115 .with_severity(ErrorSeverity::Error)
116 .with_operation(operation_str.clone()),
117 service_name:service_name_str,
118 operation:operation_str,
119 timeout_ms,
120 }
121 }
122
123 pub fn dependency_error(service_name:impl Into<String>, dependency:impl Into<String>) -> Self {
125 let service_name_str = service_name.into();
126 let dependency_str = dependency.into();
127 Self::DependencyError {
128 context:ErrorContext::new(format!(
129 "Service dependency error: {} depends on {}",
130 service_name_str, dependency_str
131 ))
132 .with_kind(ErrorKind::Service)
133 .with_severity(ErrorSeverity::Critical),
134 service_name:service_name_str,
135 dependency:dependency_str,
136 }
137 }
138}
139
140impl fmt::Display for ServiceError {
141 fn fmt(&self, f:&mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.context()) }
142}
143
144impl StdError for ServiceError {}
145
146impl From<ServiceError> for MountainError {
147 fn from(err:ServiceError) -> Self { MountainError::new(err.context().clone()).with_source(err.to_string()) }
148}