Skip to main content

systemprompt_runtime/
error.rs

1//! Typed error boundary for the runtime crate.
2//!
3//! All public APIs of `systemprompt-runtime` return [`RuntimeResult<T>`]
4//! (i.e. `Result<T, RuntimeError>`). [`RuntimeError`] composes the typed
5//! errors of upstream layers (config, database, events, files, users,
6//! extensions) via `#[from]` so callers can pattern-match on the original
7//! cause without losing fidelity.
8//!
9//! Third-party errors without a `#[from]` adapter are stringified into
10//! the [`RuntimeError::Internal`] variant at the call site so the lossy
11//! conversion is visible.
12//!
13//! Copyright (c) systemprompt.io — Business Source License 1.1.
14//! See <https://systemprompt.io> for licensing details.
15
16use systemprompt_agent::AgentError;
17use systemprompt_ai::error::RepositoryError as AiRepositoryError;
18use systemprompt_analytics::AnalyticsError;
19use systemprompt_config::{ConfigError as ProfileConfigError, ProfileBootstrapError};
20use systemprompt_content::ContentError;
21use systemprompt_database::RepositoryError;
22use systemprompt_extension::LoaderError;
23use systemprompt_files::FilesError;
24use systemprompt_mcp::McpDomainError;
25use systemprompt_models::errors::ConfigError as ModelConfigError;
26use systemprompt_models::paths::PathError;
27use systemprompt_oauth::OauthError;
28use systemprompt_users::UserError;
29use thiserror::Error;
30
31pub type RuntimeResult<T> = Result<T, RuntimeError>;
32
33#[derive(Debug, Error)]
34pub enum RuntimeError {
35    #[error(transparent)]
36    Profile(#[from] ProfileConfigError),
37
38    #[error(transparent)]
39    ProfileBootstrap(#[from] ProfileBootstrapError),
40
41    #[error(transparent)]
42    Config(#[from] ModelConfigError),
43
44    #[error(transparent)]
45    Paths(#[from] PathError),
46
47    #[error(transparent)]
48    Files(#[from] FilesError),
49
50    #[error(transparent)]
51    Users(#[from] UserError),
52
53    #[error(transparent)]
54    Repository(#[from] RepositoryError),
55
56    #[error(transparent)]
57    Analytics(#[from] AnalyticsError),
58
59    #[error(transparent)]
60    AiRepository(#[from] AiRepositoryError),
61
62    #[error(transparent)]
63    Mcp(#[from] McpDomainError),
64
65    #[error(transparent)]
66    Agent(#[from] AgentError),
67
68    #[error(transparent)]
69    Content(#[from] ContentError),
70
71    #[error(transparent)]
72    Oauth(#[from] OauthError),
73
74    #[error(transparent)]
75    Loader(#[from] LoaderError),
76
77    #[error(
78        "Configured system admin '{username}' was not found in the users table. Run `systemprompt \
79         admin bootstrap` first."
80    )]
81    SystemAdminNotFound { username: String },
82
83    #[error(
84        "Configured system admin '{username}' exists but is not active. Re-activate the user \
85         before starting the platform."
86    )]
87    SystemAdminInactive { username: String },
88
89    #[error(
90        "Configured system admin '{username}' exists but does not carry the 'admin' role. Grant \
91         the role before starting the platform."
92    )]
93    SystemAdminMissingRole { username: String },
94
95    #[error(
96        "Configured GeoIP database at '{path}' could not be loaded: {message}. Fix or remove \
97         paths.geoip_database from the profile."
98    )]
99    GeoIpUnreadable { path: String, message: String },
100
101    #[error("DATABASE_URL is empty")]
102    EmptyDatabaseUrl,
103
104    #[error("Database not found at '{path}'. Run setup first")]
105    DatabaseNotFound { path: String },
106
107    #[error("Database path '{path}' exists but is not a file")]
108    DatabaseNotFile { path: String },
109
110    #[error("internal: {0}")]
111    Internal(String),
112}