systemprompt_config/bootstrap/secrets/vault/
error.rs1pub(super) const MAX_VAULT_ERROR_CHARS: usize = 200;
12
13#[derive(Debug, thiserror::Error)]
14#[non_exhaustive]
15pub enum VaultError {
16 #[error("vault address is not a permitted outbound URL: {message}")]
17 Address { message: String },
18
19 #[error("vault TLS CA certificate at {path} could not be loaded: {message}")]
20 CaCertificate { path: String, message: String },
21
22 #[error("vault HTTP client could not be built: {message}")]
23 ClientBuild { message: String },
24
25 #[error(
26 "vault credential is missing: {name}. Provide it in the process environment; never write \
27 a token into profile YAML."
28 )]
29 MissingCredential { name: String },
30
31 #[error("vault credential file {path} could not be read: {message}")]
32 CredentialFile { path: String, message: String },
33
34 #[error("vault {method} login was rejected with HTTP {status}{detail}")]
35 Auth {
36 method: &'static str,
37 status: u16,
38 detail: String,
39 },
40
41 #[error("vault denied access to {mount}/{path} (HTTP 403){detail}")]
42 Forbidden {
43 mount: String,
44 path: String,
45 detail: String,
46 },
47
48 #[error("vault has no secret at {mount}/{path}")]
49 NotFound { mount: String, path: String },
50
51 #[error("vault returned HTTP {status} for {mount}/{path}{detail}")]
52 Http {
53 status: u16,
54 mount: String,
55 path: String,
56 detail: String,
57 },
58
59 #[error("vault response was not the expected KV v2 shape: {message}")]
60 Malformed { message: String },
61
62 #[error("vault was unreachable after {attempts} attempt(s): {message}")]
63 Exhausted { attempts: u32, message: String },
64}
65
66#[must_use]
67pub(super) fn truncate_detail(raw: &str) -> String {
68 let trimmed = raw.trim();
69 if trimmed.is_empty() {
70 return String::new();
71 }
72 let clipped: String = trimmed.chars().take(MAX_VAULT_ERROR_CHARS).collect();
73 format!(": {clipped}")
74}