use strum_macros::Display;
use tonic::Status;
#[derive(Debug, Display)]
pub enum Error {
AlreadyExists(String),
FailedPrecondition(String),
Internal(String),
InvalidArgument(String),
MigrationFailed(String),
NotFound(String),
Unavailable(String),
Unimplemented(String),
}
impl Error {
pub fn already_exists(message: impl Into<String>) -> Error {
Self::AlreadyExists(message.into())
}
pub fn failed_precondition(message: impl Into<String>) -> Error {
Self::FailedPrecondition(message.into())
}
pub fn internal(message: impl Into<String>) -> Error {
Self::Internal(message.into())
}
pub fn invalid_argument(message: impl Into<String>) -> Error {
Self::InvalidArgument(message.into())
}
pub fn migration_failed(message: impl Into<String>) -> Error {
Self::MigrationFailed(message.into())
}
pub fn not_found(message: impl Into<String>) -> Error {
Self::NotFound(message.into())
}
pub fn unavailable(message: impl Into<String>) -> Error {
Self::Unavailable(message.into())
}
pub fn unimplemented(message: impl Into<String>) -> Error {
Self::Unimplemented(message.into())
}
}
impl std::error::Error for Error {}
impl From<Error> for Status {
fn from(e: Error) -> Self {
match e {
Error::AlreadyExists(message) => Status::already_exists(message),
Error::FailedPrecondition(message) => Status::failed_precondition(message),
Error::Internal(message) => Status::internal(message),
Error::InvalidArgument(message) => Status::invalid_argument(message),
Error::MigrationFailed(message) => Status::internal(message),
Error::NotFound(message) => Status::not_found(message),
Error::Unavailable(message) => Status::unavailable(message),
Error::Unimplemented(message) => Status::unimplemented(message),
}
}
}
impl From<pbbson::Error> for Error {
fn from(e: pbbson::Error) -> Self {
Self::invalid_argument(e.to_string())
}
}
#[cfg(feature = "storage-mongodb")]
impl From<mongodb::error::Error> for Error {
fn from(e: mongodb::error::Error) -> Self {
match *e.kind {
mongodb::error::ErrorKind::Authentication { message, .. } => Self::failed_precondition(message),
mongodb::error::ErrorKind::GridFs(mongodb::error::GridFsErrorKind::FileNotFound {
identifier: _, ..
}) => Self::not_found(e.to_string()),
mongodb::error::ErrorKind::SessionsNotSupported => Self::unavailable(e.to_string()),
_ => Self::internal(e.to_string()),
}
}
}
#[cfg(feature = "storage-postgres")]
impl From<sqlx::migrate::MigrateError> for Error {
fn from(e: sqlx::migrate::MigrateError) -> Self {
Self::migration_failed(e.to_string())
}
}
#[cfg(feature = "storage-redis")]
impl From<redis::RedisError> for Error {
fn from(e: redis::RedisError) -> Self {
Self::internal(e.to_string())
}
}