use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
#[non_exhaustive]
pub enum SecretsManagerErrorCode {
#[default]
DecryptionFailure,
EncryptionFailure,
InternalServiceError,
InvalidAction,
InvalidNextTokenException,
InvalidParameterException,
InvalidRequestException,
LimitExceededException,
MalformedPolicyDocumentException,
MissingAction,
PreconditionNotMetException,
PublicPolicyException,
ResourceExistsException,
ResourceNotFoundException,
}
impl SecretsManagerErrorCode {
#[must_use]
pub fn error_type(&self) -> &'static str {
self.as_str()
}
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::DecryptionFailure => "DecryptionFailure",
Self::EncryptionFailure => "EncryptionFailure",
Self::InternalServiceError => "InternalServiceError",
Self::InvalidAction => "InvalidAction",
Self::InvalidNextTokenException => "InvalidNextTokenException",
Self::InvalidParameterException => "InvalidParameterException",
Self::InvalidRequestException => "InvalidRequestException",
Self::LimitExceededException => "LimitExceededException",
Self::MalformedPolicyDocumentException => "MalformedPolicyDocumentException",
Self::MissingAction => "MissingAction",
Self::PreconditionNotMetException => "PreconditionNotMetException",
Self::PublicPolicyException => "PublicPolicyException",
Self::ResourceExistsException => "ResourceExistsException",
Self::ResourceNotFoundException => "ResourceNotFoundException",
}
}
#[must_use]
pub fn default_status_code(&self) -> http::StatusCode {
match self {
Self::DecryptionFailure
| Self::EncryptionFailure
| Self::InvalidAction
| Self::InvalidNextTokenException
| Self::InvalidParameterException
| Self::InvalidRequestException
| Self::LimitExceededException
| Self::MalformedPolicyDocumentException
| Self::MissingAction
| Self::PreconditionNotMetException
| Self::PublicPolicyException
| Self::ResourceExistsException
| Self::ResourceNotFoundException => http::StatusCode::BAD_REQUEST,
Self::InternalServiceError => http::StatusCode::INTERNAL_SERVER_ERROR,
}
}
}
impl fmt::Display for SecretsManagerErrorCode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug)]
pub struct SecretsManagerError {
pub code: SecretsManagerErrorCode,
pub message: String,
pub status_code: http::StatusCode,
pub source: Option<Box<dyn std::error::Error + Send + Sync>>,
}
impl fmt::Display for SecretsManagerError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "SecretsManagerError({}): {}", self.code, self.message)
}
}
impl std::error::Error for SecretsManagerError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
self.source
.as_ref()
.map(|e| e.as_ref() as &(dyn std::error::Error + 'static))
}
}
impl SecretsManagerError {
#[must_use]
pub fn new(code: SecretsManagerErrorCode) -> Self {
Self {
status_code: code.default_status_code(),
message: code.as_str().to_owned(),
code,
source: None,
}
}
#[must_use]
pub fn with_message(code: SecretsManagerErrorCode, message: impl Into<String>) -> Self {
Self {
status_code: code.default_status_code(),
message: message.into(),
code,
source: None,
}
}
#[must_use]
pub fn error_type(&self) -> &'static str {
self.code.error_type()
}
#[must_use]
pub fn internal_error(message: impl Into<String>) -> Self {
Self::with_message(SecretsManagerErrorCode::InternalServiceError, message)
}
#[must_use]
pub fn missing_action() -> Self {
Self::with_message(
SecretsManagerErrorCode::MissingAction,
"Missing required header: X-Amz-Target",
)
}
#[must_use]
pub fn unknown_operation(target: &str) -> Self {
Self::with_message(
SecretsManagerErrorCode::InvalidAction,
format!("Operation {target} is not supported."),
)
}
#[must_use]
pub fn not_implemented(operation: &str) -> Self {
Self::with_message(
SecretsManagerErrorCode::InternalServiceError,
format!("Operation {operation} is not yet implemented"),
)
}
}
#[macro_export]
macro_rules! secretsmanager_error {
($code:ident) => {
$crate::error::SecretsManagerError::new($crate::error::SecretsManagerErrorCode::$code)
};
($code:ident, $msg:expr) => {
$crate::error::SecretsManagerError::with_message(
$crate::error::SecretsManagerErrorCode::$code,
$msg,
)
};
}