diff --git a/src/assignment/backends/error.rs b/src/assignment/backends/error.rs index 6f57e65d..7727a251 100644 --- a/src/assignment/backends/error.rs +++ b/src/assignment/backends/error.rs @@ -12,16 +12,17 @@ // // SPDX-License-Identifier: Apache-2.0 +use sea_orm::SqlErr; use thiserror::Error; use crate::assignment::types::*; #[derive(Error, Debug)] pub enum AssignmentDatabaseError { - #[error("role {0} not found")] + #[error("{0}")] RoleNotFound(String), - #[error("data serialization error: {}", source)] + #[error(transparent)] Serde { #[from] source: serde_json::Error, @@ -39,12 +40,30 @@ pub enum AssignmentDatabaseError { source: RoleBuilderError, }, - #[error("database error: {}", source)] - Database { - #[from] - source: sea_orm::DbErr, - }, + #[error(transparent)] + Database { source: sea_orm::DbErr }, + + /// Conflict + #[error("{0}")] + Conflict(String), - #[error("invalid assignment type: {0}")] + /// SqlError + #[error("{0}")] + Sql(String), + + #[error("{0}")] InvalidAssignmentType(String), } + +impl From for AssignmentDatabaseError { + fn from(err: sea_orm::DbErr) -> Self { + match err.sql_err() { + Some(err) => match err { + SqlErr::UniqueConstraintViolation(descr) => Self::Conflict(descr), + SqlErr::ForeignKeyConstraintViolation(descr) => Self::Conflict(descr), + other => Self::Sql(other.to_string()), + }, + None => Self::Database { source: err }, + } + } +} diff --git a/src/assignment/error.rs b/src/assignment/error.rs index 7137af0d..a25db3ad 100644 --- a/src/assignment/error.rs +++ b/src/assignment/error.rs @@ -32,15 +32,16 @@ pub enum AssignmentProviderError { source: serde_json::Error, }, + /// Conflict. + #[error("conflict: {0}")] + Conflict(String), + #[error("role {0} not found")] RoleNotFound(String), /// Assignment provider error - #[error("assignment provider database error: {}", source)] - AssignmentDatabaseError { - #[from] - source: AssignmentDatabaseError, - }, + #[error(transparent)] + AssignmentDatabaseError { source: AssignmentDatabaseError }, /// Identity provider error #[error(transparent)] @@ -68,10 +69,12 @@ pub enum AssignmentProviderError { }, } -impl AssignmentProviderError { - pub fn database(source: AssignmentDatabaseError) -> Self { +impl From for AssignmentProviderError { + fn from(source: AssignmentDatabaseError) -> Self { match source { + AssignmentDatabaseError::Conflict(x) => Self::Conflict(x), AssignmentDatabaseError::RoleNotFound(x) => Self::RoleNotFound(x), + AssignmentDatabaseError::Serde { source } => Self::Serde { source }, _ => Self::AssignmentDatabaseError { source }, } } diff --git a/src/federation/backends/error.rs b/src/federation/backends/error.rs index 75b90349..a8d15f55 100644 --- a/src/federation/backends/error.rs +++ b/src/federation/backends/error.rs @@ -19,30 +19,30 @@ use crate::federation::types::*; #[derive(Error, Debug)] pub enum FederationDatabaseError { - #[error("data serialization error")] + #[error(transparent)] Serde { #[from] source: serde_json::Error, }, - #[error("database error")] + #[error(transparent)] Database { source: sea_orm::DbErr }, - #[error("identity provider {0} not found")] + #[error("{0}")] IdentityProviderNotFound(String), - #[error("mapping provider {0} not found")] + #[error("{0}")] MappingNotFound(String), - #[error("auth state {0} not found")] + #[error("{0}")] AuthStateNotFound(String), /// Conflict - #[error("conflict: {0}")] + #[error("{0}")] Conflict(String), /// SqlError - #[error("sql error: {0}")] + #[error("{0}")] Sql(String), #[error(transparent)] diff --git a/src/federation/error.rs b/src/federation/error.rs index 882e3bc6..609a129e 100644 --- a/src/federation/error.rs +++ b/src/federation/error.rs @@ -46,7 +46,7 @@ pub enum FederationProviderError { MappingTokenProjectDomainUnset, /// Conflict. - #[error("oha {0}")] + #[error("conflict: {0}")] Conflict(String), /// Identity provider error. @@ -62,6 +62,7 @@ impl From for FederationProviderError { } FederationDatabaseError::MappingNotFound(x) => Self::MappingNotFound(x), FederationDatabaseError::Conflict(x) => Self::Conflict(x), + FederationDatabaseError::Serde { source } => Self::Serde { source }, _ => Self::FederationDatabase { source }, } } diff --git a/src/identity/backends/error.rs b/src/identity/backends/error.rs index c0510656..153a4f4c 100644 --- a/src/identity/backends/error.rs +++ b/src/identity/backends/error.rs @@ -12,6 +12,7 @@ // // SPDX-License-Identifier: Apache-2.0 +use sea_orm::SqlErr; use thiserror::Error; use crate::identity::error::IdentityProviderPasswordHashError; @@ -22,13 +23,13 @@ pub enum IdentityDatabaseError { #[error("corrupted database entries for user {0}")] MalformedUser(String), - #[error("user {0} not found")] + #[error("{0}")] UserNotFound(String), - #[error("group {0} not found")] + #[error("{0}")] GroupNotFound(String), - #[error("data serialization error")] + #[error(transparent)] Serde { #[from] source: serde_json::Error, @@ -46,11 +47,16 @@ pub enum IdentityDatabaseError { source: FederationBuilderError, }, - #[error("database data")] - Database { - #[from] - source: sea_orm::DbErr, - }, + /// Conflict + #[error("{0}")] + Conflict(String), + + /// SqlError + #[error("{0}")] + Sql(String), + + #[error(transparent)] + Database { source: sea_orm::DbErr }, #[error("password hashing error")] PasswordHash { @@ -61,3 +67,16 @@ pub enum IdentityDatabaseError { #[error("either user id or user name with user domain id or name must be given")] UserIdOrNameWithDomain, } + +impl From for IdentityDatabaseError { + fn from(err: sea_orm::DbErr) -> Self { + match err.sql_err() { + Some(err) => match err { + SqlErr::UniqueConstraintViolation(descr) => Self::Conflict(descr), + SqlErr::ForeignKeyConstraintViolation(descr) => Self::Conflict(descr), + other => Self::Sql(other.to_string()), + }, + None => Self::Database { source: err }, + } + } +} diff --git a/src/identity/backends/sql.rs b/src/identity/backends/sql.rs index 41203948..47bfb66b 100644 --- a/src/identity/backends/sql.rs +++ b/src/identity/backends/sql.rs @@ -154,9 +154,7 @@ impl IdentityBackend for SqlBackend { db: &DatabaseConnection, user_id: &'a str, ) -> Result<(), IdentityProviderError> { - user::delete(&self.config, db, user_id) - .await - .map_err(IdentityProviderError::database) + Ok(user::delete(&self.config, db, user_id).await?) } /// List groups @@ -196,9 +194,7 @@ impl IdentityBackend for SqlBackend { db: &DatabaseConnection, group_id: &'a str, ) -> Result<(), IdentityProviderError> { - group::delete(&self.config, db, group_id) - .await - .map_err(IdentityProviderError::database) + Ok(group::delete(&self.config, db, group_id).await?) } /// List groups a user is member of @@ -281,9 +277,7 @@ impl IdentityBackend for SqlBackend { db: &DatabaseConnection, user_id: &'a str, ) -> Result<(), IdentityProviderError> { - passkey_state::delete(db, user_id) - .await - .map_err(IdentityProviderError::database) + Ok(passkey_state::delete(db, user_id).await?) } /// Delete passkey auth state for a user @@ -293,9 +287,7 @@ impl IdentityBackend for SqlBackend { db: &DatabaseConnection, user_id: &'a str, ) -> Result<(), IdentityProviderError> { - passkey_state::delete(db, user_id) - .await - .map_err(IdentityProviderError::database) + Ok(passkey_state::delete(db, user_id).await?) } } diff --git a/src/identity/error.rs b/src/identity/error.rs index fb11d287..189a8971 100644 --- a/src/identity/error.rs +++ b/src/identity/error.rs @@ -40,10 +40,7 @@ pub enum IdentityProviderError { /// Identity provider error #[error(transparent)] - IdentityDatabase { - #[from] - source: IdentityDatabaseError, - }, + IdentityDatabase { source: IdentityDatabaseError }, #[error(transparent)] UserBuilder { @@ -90,15 +87,21 @@ pub enum IdentityProviderError { source: ResourceProviderError, }, + /// Conflict. + #[error("conflict: {0}")] + Conflict(String), + #[error("wrong username or password")] WrongUsernamePassword, } -impl IdentityProviderError { - pub fn database(source: IdentityDatabaseError) -> Self { +impl From for IdentityProviderError { + fn from(source: IdentityDatabaseError) -> Self { match source { + IdentityDatabaseError::Conflict(x) => Self::Conflict(x), IdentityDatabaseError::UserNotFound(x) => Self::UserNotFound(x), IdentityDatabaseError::GroupNotFound(x) => Self::GroupNotFound(x), + IdentityDatabaseError::Serde { source } => Self::Serde { source }, _ => Self::IdentityDatabase { source }, } } diff --git a/src/resource/backends/error.rs b/src/resource/backends/error.rs index 57524d12..c6166bef 100644 --- a/src/resource/backends/error.rs +++ b/src/resource/backends/error.rs @@ -12,36 +12,55 @@ // // SPDX-License-Identifier: Apache-2.0 +use sea_orm::SqlErr; use thiserror::Error; use crate::resource::types::*; #[derive(Error, Debug)] pub enum ResourceDatabaseError { - #[error("domain {0} not found")] + #[error("{0}")] DomainNotFound(String), - #[error("data serialization error")] + #[error(transparent)] Serde { #[from] source: serde_json::Error, }, - #[error("error building domain data")] + #[error(transparent)] DomainBuilderError { #[from] source: DomainBuilderError, }, - #[error("error building project data")] + #[error(transparent)] ProjectBuilderError { #[from] source: ProjectBuilderError, }, - #[error("database data")] - Database { - #[from] - source: sea_orm::DbErr, - }, + /// Conflict + #[error("{0}")] + Conflict(String), + + /// SqlError + #[error("{0}")] + Sql(String), + + #[error(transparent)] + Database { source: sea_orm::DbErr }, +} + +impl From for ResourceDatabaseError { + fn from(err: sea_orm::DbErr) -> Self { + match err.sql_err() { + Some(err) => match err { + SqlErr::UniqueConstraintViolation(descr) => Self::Conflict(descr), + SqlErr::ForeignKeyConstraintViolation(descr) => Self::Conflict(descr), + other => Self::Sql(other.to_string()), + }, + None => Self::Database { source: err }, + } + } } diff --git a/src/resource/error.rs b/src/resource/error.rs index 53b8607c..5bed85ee 100644 --- a/src/resource/error.rs +++ b/src/resource/error.rs @@ -19,11 +19,15 @@ use crate::resource::types::DomainBuilderError; #[derive(Error, Debug)] pub enum ResourceProviderError { - /// Unsupported driver + /// Unsupported driver. #[error("unsupported driver {0}")] UnsupportedDriver(String), - /// Identity provider error + /// Conflict. + #[error("conflict: {0}")] + Conflict(String), + + /// Data (de)serialization error. #[error("data serialization error")] Serde { #[from] @@ -35,10 +39,7 @@ pub enum ResourceProviderError { /// Identity provider error #[error(transparent)] - ResourceDatabase { - #[from] - source: ResourceDatabaseError, - }, + ResourceDatabase { source: ResourceDatabaseError }, #[error(transparent)] DomainBuilder { @@ -47,9 +48,10 @@ pub enum ResourceProviderError { }, } -impl ResourceProviderError { - pub fn database(source: ResourceDatabaseError) -> Self { +impl From for ResourceProviderError { + fn from(source: ResourceDatabaseError) -> Self { match source { + ResourceDatabaseError::Conflict(x) => Self::Conflict(x), ResourceDatabaseError::DomainNotFound(x) => Self::DomainNotFound(x), _ => Self::ResourceDatabase { source }, }