rustack_ssm_model/
error.rs1use std::fmt;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
11#[non_exhaustive]
12pub enum SsmErrorCode {
13 ParameterNotFound,
15 ParameterAlreadyExists,
17 ParameterMaxVersionLimitExceeded,
19 ParameterVersionNotFound,
21 ParameterVersionLabelLimitExceeded,
23 HierarchyLevelLimitExceeded,
25 HierarchyTypeMismatch,
27 InvalidAllowedPatternException,
29 ParameterPatternMismatchException,
31 InvalidFilterKey,
33 InvalidFilterOption,
35 InvalidFilterValue,
37 InvalidNextToken,
39 InvalidResourceId,
41 InvalidResourceType,
43 UnsupportedParameterType,
45 TooManyTagsError,
47 InternalServerError,
49 InvalidSecurity,
51 InvalidAction,
53 MissingAction,
55 #[default]
57 ValidationException,
58}
59
60impl SsmErrorCode {
61 #[must_use]
66 pub fn error_type(&self) -> &'static str {
67 self.as_str()
68 }
69
70 #[must_use]
72 pub fn as_str(&self) -> &'static str {
73 match self {
74 Self::ParameterNotFound => "ParameterNotFound",
75 Self::ParameterAlreadyExists => "ParameterAlreadyExists",
76 Self::ParameterMaxVersionLimitExceeded => "ParameterMaxVersionLimitExceeded",
77 Self::ParameterVersionNotFound => "ParameterVersionNotFound",
78 Self::ParameterVersionLabelLimitExceeded => "ParameterVersionLabelLimitExceeded",
79 Self::HierarchyLevelLimitExceeded => "HierarchyLevelLimitExceeded",
80 Self::HierarchyTypeMismatch => "HierarchyTypeMismatch",
81 Self::InvalidAllowedPatternException => "InvalidAllowedPatternException",
82 Self::ParameterPatternMismatchException => "ParameterPatternMismatchException",
83 Self::InvalidFilterKey => "InvalidFilterKey",
84 Self::InvalidFilterOption => "InvalidFilterOption",
85 Self::InvalidFilterValue => "InvalidFilterValue",
86 Self::InvalidNextToken => "InvalidNextToken",
87 Self::InvalidResourceId => "InvalidResourceId",
88 Self::InvalidResourceType => "InvalidResourceType",
89 Self::UnsupportedParameterType => "UnsupportedParameterType",
90 Self::TooManyTagsError => "TooManyTagsError",
91 Self::InternalServerError => "InternalServerError",
92 Self::InvalidSecurity => "InvalidSecurity",
93 Self::InvalidAction => "InvalidAction",
94 Self::MissingAction => "MissingAction",
95 Self::ValidationException => "ValidationException",
96 }
97 }
98
99 #[must_use]
101 pub fn default_status_code(&self) -> http::StatusCode {
102 match self {
103 Self::InternalServerError => http::StatusCode::INTERNAL_SERVER_ERROR,
104 _ => http::StatusCode::BAD_REQUEST,
105 }
106 }
107}
108
109impl fmt::Display for SsmErrorCode {
110 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111 f.write_str(self.as_str())
112 }
113}
114
115#[derive(Debug)]
117pub struct SsmError {
118 pub code: SsmErrorCode,
120 pub message: String,
122 pub status_code: http::StatusCode,
124 pub source: Option<Box<dyn std::error::Error + Send + Sync>>,
126}
127
128impl fmt::Display for SsmError {
129 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
130 write!(f, "SsmError({}): {}", self.code, self.message)
131 }
132}
133
134impl std::error::Error for SsmError {
135 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
136 self.source
137 .as_ref()
138 .map(|e| e.as_ref() as &(dyn std::error::Error + 'static))
139 }
140}
141
142impl SsmError {
143 #[must_use]
145 pub fn new(code: SsmErrorCode) -> Self {
146 Self {
147 status_code: code.default_status_code(),
148 message: code.as_str().to_owned(),
149 code,
150 source: None,
151 }
152 }
153
154 #[must_use]
156 pub fn with_message(code: SsmErrorCode, message: impl Into<String>) -> Self {
157 Self {
158 status_code: code.default_status_code(),
159 message: message.into(),
160 code,
161 source: None,
162 }
163 }
164
165 #[must_use]
167 pub fn with_source(mut self, source: impl std::error::Error + Send + Sync + 'static) -> Self {
168 self.source = Some(Box::new(source));
169 self
170 }
171
172 #[must_use]
174 pub fn error_type(&self) -> &'static str {
175 self.code.error_type()
176 }
177
178 #[must_use]
182 pub fn parameter_not_found(name: &str) -> Self {
183 Self::with_message(SsmErrorCode::ParameterNotFound, name.to_owned())
184 }
185
186 #[must_use]
188 pub fn parameter_already_exists(name: &str) -> Self {
189 Self::with_message(
190 SsmErrorCode::ParameterAlreadyExists,
191 format!(
192 "The parameter {name} already exists. To overwrite this value, set the overwrite \
193 option in the request to true."
194 ),
195 )
196 }
197
198 #[must_use]
200 pub fn validation(message: impl Into<String>) -> Self {
201 Self::with_message(SsmErrorCode::ValidationException, message)
202 }
203
204 #[must_use]
206 pub fn internal_error(message: impl Into<String>) -> Self {
207 Self::with_message(SsmErrorCode::InternalServerError, message)
208 }
209
210 #[must_use]
212 pub fn missing_action() -> Self {
213 Self::with_message(
214 SsmErrorCode::MissingAction,
215 "Missing required header: X-Amz-Target",
216 )
217 }
218
219 #[must_use]
221 pub fn unknown_operation(target: &str) -> Self {
222 Self::with_message(
223 SsmErrorCode::InvalidAction,
224 format!(
225 "Operation {target} is not supported. Only Parameter Store operations are \
226 implemented."
227 ),
228 )
229 }
230
231 #[must_use]
233 pub fn not_implemented(operation: &str) -> Self {
234 Self::with_message(
235 SsmErrorCode::InternalServerError,
236 format!("Operation {operation} is not yet implemented"),
237 )
238 }
239}
240
241#[macro_export]
256macro_rules! ssm_error {
257 ($code:ident) => {
258 $crate::error::SsmError::new($crate::error::SsmErrorCode::$code)
259 };
260 ($code:ident, $msg:expr) => {
261 $crate::error::SsmError::with_message($crate::error::SsmErrorCode::$code, $msg)
262 };
263}