Skip to main content

allowthem_saas/
error.rs

1use allowthem_core::AuthError;
2
3#[derive(Debug, thiserror::Error)]
4pub enum SaasError {
5    #[error("slug is already taken")]
6    SlugTaken,
7    #[error("slug is invalid: {0}")]
8    SlugInvalid(&'static str),
9    #[error("slug is reserved")]
10    SlugReserved,
11    #[error("tenant not found")]
12    TenantNotFound,
13    #[error("slug cannot be changed after first login")]
14    SlugChangeAfterFirstLogin,
15    #[error("provisioning failed: {0}")]
16    ProvisionFailed(String),
17    #[error("invalid tenant role: {0}")]
18    InvalidRole(String),
19    #[error("member already exists for that email")]
20    MemberAlreadyExists,
21    #[error("invite token not found or expired")]
22    InviteNotFoundOrExpired,
23    #[error("member not found")]
24    MemberNotFound,
25    #[error("cannot demote the only remaining owner")]
26    CannotDemoteLastOwner,
27    #[error("cannot remove the only remaining owner")]
28    CannotRemoveLastOwner,
29    #[error("domain already exists")]
30    DomainAlreadyExists,
31    #[error("domain not found")]
32    DomainNotFound,
33    #[error("invalid domain: {0}")]
34    DomainInvalid(&'static str),
35    #[error("dns error: {0}")]
36    Dns(String),
37    #[error(transparent)]
38    Auth(#[from] AuthError),
39    #[error(transparent)]
40    Db(#[from] sqlx::Error),
41    #[error(transparent)]
42    Io(#[from] std::io::Error),
43}
44
45fn is_unique_violation(e: &sqlx::Error) -> bool {
46    matches!(e, sqlx::Error::Database(db_err) if db_err.is_unique_violation())
47}
48
49pub(crate) fn map_slug_conflict(e: sqlx::Error) -> SaasError {
50    if is_unique_violation(&e) {
51        SaasError::SlugTaken
52    } else {
53        SaasError::Db(e)
54    }
55}