use thiserror::Error;
use crate::error::codes::{ErrorCode, PublicError, ToPublicError};
pub type ManagerResult<T> = Result<T, ManagerError>;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ErrorCategory {
Retryable,
NonRetryable,
}
#[derive(Error, Debug, Clone, PartialEq)]
pub enum ManagerError {
#[error("Resource not found: {0}")]
NotFound(String),
#[error("Resource already exists: {0}")]
AlreadyExists(String),
#[error("Invalid input: {0}")]
InvalidInput(String),
#[error("Storage error: {0}")]
StorageError(String),
#[error("Schema error: {0}")]
SchemaError(String),
#[error("Transaction error: {0}")]
TransactionError(String),
#[error("Timeout error: {0}")]
TimeoutError(String),
#[error("Other error: {0}")]
Other(String),
}
impl ManagerError {
pub fn category(&self) -> ErrorCategory {
match self {
ManagerError::StorageError(_) | ManagerError::TimeoutError(_) => {
ErrorCategory::Retryable
}
_ => ErrorCategory::NonRetryable,
}
}
pub fn is_retryable(&self) -> bool {
matches!(self.category(), ErrorCategory::Retryable)
}
pub fn not_found(msg: impl Into<String>) -> Self {
Self::NotFound(msg.into())
}
pub fn already_exists(msg: impl Into<String>) -> Self {
Self::AlreadyExists(msg.into())
}
pub fn invalid_input(msg: impl Into<String>) -> Self {
Self::InvalidInput(msg.into())
}
pub fn storage_error(msg: impl Into<String>) -> Self {
Self::StorageError(msg.into())
}
pub fn schema_error(msg: impl Into<String>) -> Self {
Self::SchemaError(msg.into())
}
pub fn transaction_error(msg: impl Into<String>) -> Self {
Self::TransactionError(msg.into())
}
pub fn timeout_error(msg: impl Into<String>) -> Self {
Self::TimeoutError(msg.into())
}
}
impl ToPublicError for ManagerError {
fn to_public_error(&self) -> PublicError {
PublicError::new(self.to_error_code(), self.to_public_message())
}
fn to_error_code(&self) -> ErrorCode {
match self {
ManagerError::NotFound(_) => ErrorCode::ResourceNotFound,
ManagerError::AlreadyExists(_) => ErrorCode::ResourceAlreadyExists,
ManagerError::InvalidInput(_) => ErrorCode::InvalidInput,
ManagerError::TimeoutError(_) => ErrorCode::Timeout,
_ => ErrorCode::InternalError,
}
}
fn to_public_message(&self) -> String {
self.to_string()
}
}