use thiserror::Error;
#[derive(Debug, Error)]
pub enum GuardError {
#[error("invalid token")]
InvalidToken,
#[error("session expired")]
SessionExpired,
#[error("session revoked")]
SessionRevoked,
#[error("policy denied: {0}")]
PolicyDenied(String),
#[error("database error: {0}")]
DatabaseError(#[from] sqlx::Error),
#[error("config error: {0}")]
ConfigError(String),
#[error("serialization error: {0}")]
SerializationError(#[from] serde_json::Error),
#[error("io error: {0}")]
IoError(#[from] std::io::Error),
#[error("migration error: {0}")]
MigrationError(#[from] sqlx::migrate::MigrateError),
#[error("jwt error")]
JwtError(#[from] jsonwebtoken::errors::Error),
#[error("toml parse error: {0}")]
TomlError(#[from] toml::de::Error),
#[error("uuid parse error: {0}")]
UuidError(#[from] uuid::Error),
#[error("audit channel closed")]
AuditChannelClosed,
}
impl From<GuardError> for tonic::Status {
fn from(value: GuardError) -> Self {
match value {
GuardError::InvalidToken => tonic::Status::unauthenticated("invalid token"),
GuardError::SessionExpired | GuardError::SessionRevoked => {
tonic::Status::unauthenticated(value.to_string())
}
GuardError::PolicyDenied(reason) => tonic::Status::permission_denied(reason),
GuardError::ConfigError(message) => tonic::Status::invalid_argument(message),
GuardError::DatabaseError(_)
| GuardError::MigrationError(_)
| GuardError::AuditChannelClosed => tonic::Status::unavailable(value.to_string()),
_ => tonic::Status::internal(value.to_string()),
}
}
}
pub type GuardResult<T> = Result<T, GuardError>;