Skip to main content

systemprompt_loader/
error.rs

1//! Error types raised by the loader infrastructure.
2//!
3//! Three thiserror-derived enums cover the public surface:
4//!
5//! - [`ConfigLoadError`] — services-config reading, YAML parsing, include
6//!   resolution, and validation failures.
7//! - [`ConfigWriteError`] — file creation, agent CRUD, and config-file editing
8//!   failures.
9//! - [`ExtensionLoadError`] — manifest discovery and registry lookups.
10//!
11//! All three implement `std::error::Error` and compose with upstream
12//! errors (`std::io::Error`, `serde_yaml::Error`,
13//! `systemprompt_config::ProfileBootstrapError`,
14//! `systemprompt_models::ServicesValidationError`,
15//! `systemprompt_models::ProfileValidationError`) via `#[from]`.
16
17use std::path::PathBuf;
18use thiserror::Error;
19
20#[derive(Debug, Error)]
21pub enum ConfigLoadError {
22    #[error("profile bootstrap unavailable: {0}")]
23    ProfileBootstrap(String),
24
25    #[error("io error at {path}: {source}")]
26    Io {
27        path: PathBuf,
28        #[source]
29        source: std::io::Error,
30    },
31
32    #[error("yaml parse failure at {path}: {source}")]
33    Yaml {
34        path: PathBuf,
35        #[source]
36        source: serde_yaml::Error,
37    },
38
39    #[error(
40        "include file not found: {include}\nReferenced in: {referrer}\nEither create the file or \
41         remove it from the includes list."
42    )]
43    IncludeNotFound { include: PathBuf, referrer: PathBuf },
44
45    #[error("include cycle detected: {chain}")]
46    IncludeCycle { chain: String },
47
48    #[error("duplicate agent definition: {0}")]
49    DuplicateAgent(String),
50
51    #[error("duplicate MCP server definition: {0}")]
52    DuplicateMcpServer(String),
53
54    #[error("duplicate plugin definition: {0}")]
55    DuplicatePlugin(String),
56
57    #[error("duplicate skill definition: {0}")]
58    DuplicateSkill(String),
59
60    #[error("duplicate content source definition: {0}")]
61    DuplicateContentSource(String),
62
63    #[error("services config validation failed: {0}")]
64    Validation(String),
65}
66
67#[derive(Debug, Error)]
68pub enum ConfigWriteError {
69    #[error("io error at {path}: {source}")]
70    Io {
71        path: PathBuf,
72        #[source]
73        source: std::io::Error,
74    },
75
76    #[error("yaml serialisation failed: {0}")]
77    YamlEncode(#[from] serde_yaml::Error),
78
79    #[error("Agent file already exists: {0}. Use 'agents edit' to modify.")]
80    AgentFileExists(PathBuf),
81
82    #[error("Agent '{0}' not found in any configuration file")]
83    AgentNotFound(String),
84}
85
86#[derive(Debug, Error)]
87pub enum ExtensionLoadError {
88    #[error("Binary '{name}' not found at {path}")]
89    BinaryNotFound { name: String, path: PathBuf },
90
91    #[error("No manifest.yaml found for extension '{0}' in extensions/")]
92    ManifestMissing(String),
93}
94
95pub type ConfigLoadResult<T> = Result<T, ConfigLoadError>;
96
97pub type ConfigWriteResult<T> = Result<T, ConfigWriteError>;
98
99pub type ExtensionLoadResult<T> = Result<T, ExtensionLoadError>;
100
101#[derive(Debug, Error)]
102pub enum ProfileLoadError {
103    #[error("io error at {path}: {source}")]
104    Io {
105        path: PathBuf,
106        #[source]
107        source: std::io::Error,
108    },
109
110    #[error(transparent)]
111    Profile(#[from] systemprompt_models::profile::ProfileError),
112}
113
114pub type ProfileLoadResult<T> = Result<T, ProfileLoadError>;