1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//! Tenancy errors.
//!
//! Slice 1 ships a small surface — `Resolution`, `Validation`,
//! `Driver`. Later slices will grow the variants (e.g. `SecretsResolve`,
//! `PoolExhausted`, `MissingApex`).
use crate::sql::sqlx;
use super::secrets::SecretsError;
/// Errors raised while resolving, provisioning, or operating on
/// tenants.
#[derive(Debug, thiserror::Error)]
pub enum TenancyError {
/// Per-request tenant resolution failed — no `Org` matched the
/// request's host / path / header / port. The handler should
/// usually surface this as 404.
#[error("tenant resolution failed: {0}")]
Resolution(String),
/// User-supplied data (slug, host_pattern, database_url shape)
/// is internally inconsistent or violates a uniqueness invariant.
#[error("tenancy validation: {0}")]
Validation(String),
/// `Org.database_url` resolution via [`super::SecretsResolver`]
/// failed (vault outage, missing env var, malformed reference).
/// `migrate_tenants` skips the affected tenant and logs; the
/// resolver layer surfaces it as a hard error.
#[error("secrets resolution failed: {0}")]
Secrets(#[from] SecretsError),
/// Migration runner errors (file I/O, JSON, validation, SQL)
/// surfaced from `crate::migrate::MigrateError` while running
/// per-tenant migrations.
#[error(transparent)]
Migrate(#[from] rustango::migrate::MigrateError),
/// Per-tenant query orchestration errors (compile/validation/SQL)
/// surfaced from `crate::sql::ExecError`.
#[error(transparent)]
Exec(#[from] rustango::sql::ExecError),
/// SQL or pool-management failure (raw sqlx error).
#[error(transparent)]
Driver(#[from] sqlx::Error),
/// I/O failure when writing user-facing output through the
/// `manage` runner's writer (broken pipe etc.).
#[error(transparent)]
Io(#[from] std::io::Error),
}