systemprompt_config/
error.rs1use std::path::PathBuf;
15
16use systemprompt_models::errors::SecretsError;
17use systemprompt_models::profile::{GatewayProfileError, ProfileError};
18
19use crate::bootstrap::{ProfileBootstrapError, SecretsBootstrapError};
20use crate::services::ConfigValidationError;
21
22pub type ConfigResult<T> = Result<T, ConfigError>;
23
24#[derive(Debug, thiserror::Error)]
25#[non_exhaustive]
26pub enum ConfigError {
27 #[error("Config already initialized")]
28 AlreadyInitialized,
29
30 #[error(transparent)]
31 Profile(#[from] ProfileBootstrapError),
32
33 #[error(transparent)]
34 Secrets(#[from] SecretsBootstrapError),
35
36 #[error(transparent)]
37 ProfileParse(#[from] ProfileError),
38
39 #[error(transparent)]
40 Gateway(#[from] GatewayProfileError),
41
42 #[error(transparent)]
43 SchemaValidation(#[from] ConfigValidationError),
44
45 #[error(transparent)]
46 SecretsParse(#[from] SecretsError),
47
48 #[error(transparent)]
49 Io(#[from] std::io::Error),
50
51 #[error(transparent)]
52 Json(#[from] serde_json::Error),
53
54 #[error(transparent)]
55 Yaml(#[from] serde_yaml::Error),
56
57 #[error("Missing required path: paths.{field}")]
58 MissingProfilePath { field: String },
59
60 #[error("Failed to canonicalize {name} path: {source}")]
61 CanonicalizePath {
62 name: String,
63 #[source]
64 source: std::io::Error,
65 },
66
67 #[error("Profile path '{field}' cannot be read: {path}")]
68 ReadProfilePath {
69 field: String,
70 path: PathBuf,
71 #[source]
72 source: std::io::Error,
73 },
74
75 #[error("Profile path '{field}' has invalid YAML: {path}")]
76 InvalidProfileYaml {
77 field: String,
78 path: PathBuf,
79 #[source]
80 source: serde_yaml::Error,
81 },
82
83 #[error("Profile path validation failed: {message}")]
84 ProfilePathReport { message: String },
85
86 #[error("Unsupported database type '{db_type}'. Only 'postgres' is supported.")]
87 UnsupportedDatabaseType { db_type: String },
88
89 #[error("Invalid database URL: {message}")]
90 InvalidDatabaseUrl { message: String },
91
92 #[error("Failed to resolve variables after {passes} passes: {unresolved}")]
93 UnresolvedVariables { passes: usize, unresolved: String },
94
95 #[error("{count} validation error(s)")]
96 ValidationErrors { count: usize },
97
98 #[error("Required config file missing: {path}")]
99 EnvironmentConfigMissing { path: PathBuf },
100
101 #[error(
102 "Profile is missing required `system_admin.username` and `SYSTEMPROMPT_SYSTEM_ADMIN` is \
103 not set. The platform refuses to start without an explicit system-admin identity."
104 )]
105 MissingSystemAdmin,
106
107 #[error("No provider named {name}")]
108 ProviderNotFound { name: String },
109
110 #[error("No model with id {id} under provider {provider}")]
111 ModelNotFound { id: String, provider: String },
112
113 #[error("Access token expiry must be positive")]
114 NonPositiveAccessTokenExpiry,
115
116 #[error("Refresh token expiry must be positive")]
117 NonPositiveRefreshTokenExpiry,
118
119 #[error("No trusted issuer found with issuer {issuer}")]
120 TrustedIssuerNotFound { issuer: String },
121
122 #[error("{message}")]
123 Other { message: String },
124}
125
126impl ConfigError {
127 pub fn other(message: impl Into<String>) -> Self {
128 Self::Other {
129 message: message.into(),
130 }
131 }
132}