Skip to main content

boatramp_node/
error.rs

1//! Assembly errors surfaced by the node-library helpers (moved out of the
2//! binary's `serve::Error`, which absorbs them via `#[from]`). Scoped to the
3//! handler/SQL assembly today; grows as more of `assemble()` moves here.
4
5/// A node-assembly error. Variants are feature-gated to the assembly path that
6/// produces them, matching the crate's forwarded features.
7#[derive(Debug, thiserror::Error)]
8pub enum Error {
9    /// A token root **private** key (hex) failed to parse, or an external signer
10    /// (KMS/HSM/Vault) failed to build / resolve its public key.
11    #[error("invalid auth root private key: {0}")]
12    AuthPrivKey(String),
13    /// A token root **public** key (hex) failed to parse.
14    #[error("invalid auth root public key: {0}")]
15    AuthPubKey(String),
16    /// Refusing to bind a non-loopback address with control-plane auth disabled.
17    /// Set auth keys, bind a loopback address, or — for local dev —
18    /// relax `allow_unauthenticated_public_bind` in `[security]` (the `dev` profile).
19    #[error(
20        "refusing to bind {addr} with control-plane auth disabled: an \
21         unauthenticated control plane must not be exposed to a non-loopback \
22         address. Configure auth keys, bind a loopback address, or set the `dev` \
23         security profile / `allow_unauthenticated_public_bind` for local dev"
24    )]
25    UnauthenticatedPublicBind { addr: std::net::SocketAddr },
26
27    /// A handler `sql` binding named an env var that is not set.
28    #[cfg(feature = "handlers")]
29    #[error("handlers SQL binding: env var {0} is not set")]
30    SqlEnvUnset(String),
31    /// A cluster sqld `url` was set without the required `admin_url`.
32    #[cfg(feature = "handlers")]
33    #[error("handlers SQL binding: `url` (cluster sqld) requires `admin_url`")]
34    SqlAdminUrlRequired,
35    /// An unrecognised `[handlers.bindings.sql].preview_mode`.
36    #[cfg(feature = "handlers")]
37    #[error("handlers SQL binding: unknown preview_mode {0:?} (expected empty | branch | shared)")]
38    UnknownPreviewMode(String),
39    /// Reading the `preview_init` SQL script failed.
40    #[cfg(feature = "handlers")]
41    #[error("handlers SQL binding: reading preview_init {path:?}: {source}")]
42    PreviewInitRead {
43        path: std::path::PathBuf,
44        #[source]
45        source: std::io::Error,
46    },
47    /// An external database named an unrecognised engine `kind`.
48    #[cfg(any(feature = "sql-postgres", feature = "sql-mysql"))]
49    #[error("handlers SQL binding: external database {name:?} has unknown kind {kind:?} (expected postgres | mysql)")]
50    SqlExternalKind { name: String, kind: String },
51    /// An external database entry omitted the required `url_env`.
52    #[cfg(any(feature = "sql-postgres", feature = "sql-mysql"))]
53    #[error("handlers SQL binding: external database {0:?} is missing `url_env`")]
54    SqlExternalUrlEnvMissing(String),
55    /// Building an external database backend (pool/URL parse) failed.
56    #[cfg(any(feature = "sql-postgres", feature = "sql-mysql"))]
57    #[error("handlers SQL binding: external database {name:?}: {source}")]
58    SqlExternalConnect {
59        name: String,
60        #[source]
61        source: boatramp_core::sql::SqlError,
62    },
63    /// A managed compute-backed database (no `password_env`) was configured but no
64    /// `[secrets]` envelope is set — boatramp refuses to manage a credential it
65    /// cannot seal (it would otherwise store the DB password in cleartext).
66    #[cfg(any(feature = "sql-postgres", feature = "sql-mysql"))]
67    #[error(
68        "handlers SQL binding: managed database {0:?} needs a `[secrets]` envelope to seal its \
69         generated credential — set `[secrets]` (envelope = \"local\" or \"vault\"), or supply \
70         `password_env` to bring your own"
71    )]
72    SqlManagedNeedsSecrets(String),
73    /// Generating/sealing/reading a managed compute-backed database credential failed.
74    #[cfg(any(feature = "sql-postgres", feature = "sql-mysql"))]
75    #[error("handlers SQL binding: managed database {name:?}: {reason}")]
76    SqlManagedCredential { name: String, reason: String },
77    /// External databases were configured but this build has no external SQL
78    /// engine compiled in.
79    #[cfg(all(
80        feature = "handlers",
81        not(any(feature = "sql-postgres", feature = "sql-mysql"))
82    ))]
83    #[error("handlers SQL binding: external database {0:?} needs an external SQL engine — rebuild with --features sql-postgres and/or sql-mysql")]
84    SqlExternalUnavailable(String),
85
86    /// `--kv slatedb` selected but this build lacks SlateDB support.
87    #[cfg(not(feature = "slatedb"))]
88    #[error("this build has no slatedb support; rebuild with `--features slatedb`")]
89    NoSlatedbSupport,
90    /// `--kv cloudflare` selected but this build lacks Cloudflare KV support.
91    #[cfg(not(feature = "cloudflare-kv"))]
92    #[error("this build has no Cloudflare KV support; rebuild with `--features cloudflare-kv`")]
93    NoCloudflareKvSupport,
94    /// Opening the KV store (SlateDB / Cloudflare) failed.
95    #[cfg(any(feature = "slatedb", feature = "cloudflare-kv"))]
96    #[error(transparent)]
97    Kv(#[from] boatramp_core::kv::KvError),
98
99    /// `--blobs fs` selected but this build lacks filesystem blob support.
100    #[cfg(not(feature = "fs"))]
101    #[error("this build has no filesystem blob support; rebuild with `--features fs`")]
102    NoFsSupport,
103    /// `--blobs s3` selected but this build lacks S3 support.
104    #[cfg(not(feature = "s3"))]
105    #[error("this build has no S3 support; rebuild with `--features s3`")]
106    NoS3Support,
107    /// `--blobs gcs` selected but this build lacks GCS support.
108    #[cfg(not(feature = "gcs"))]
109    #[error("this build has no GCS support; rebuild with `--features gcs`")]
110    NoGcsSupport,
111    /// `--blobs azure` selected but this build lacks Azure support.
112    #[cfg(not(feature = "azure"))]
113    #[error("this build has no Azure support; rebuild with `--features azure`")]
114    NoAzureSupport,
115    /// `--blobs s3` without `--s3-bucket`.
116    #[cfg(feature = "s3")]
117    #[error("--s3-bucket is required for --blobs s3")]
118    S3BucketRequired,
119    /// `--blobs gcs` was selected without a bucket.
120    #[cfg(feature = "gcs")]
121    #[error("--gcs-bucket is required for --blobs gcs")]
122    GcsBucketRequired,
123    /// Connecting the GCS backend failed (usually credential resolution).
124    #[cfg(feature = "gcs")]
125    #[error("GCS backend: {0}")]
126    GcsConnect(String),
127    /// `--blobs azure` was selected without an account/container.
128    #[cfg(feature = "azure")]
129    #[error("--azure-account and --azure-container are required for --blobs azure")]
130    AzureConfigRequired,
131    /// Connecting the Azure backend failed.
132    #[cfg(feature = "azure")]
133    #[error("Azure backend: {0}")]
134    AzureConnect(String),
135
136    /// Building the wasm handler engine failed.
137    #[cfg(feature = "handlers")]
138    #[error(transparent)]
139    Handler(#[from] boatramp_handlers::HandlerError),
140
141    /// Building the `[secrets]` envelope (local KEK / Vault) failed.
142    #[error("secrets envelope: {0}")]
143    Envelope(String),
144}
145
146/// Node-assembly result alias.
147pub type Result<T> = std::result::Result<T, Error>;