Skip to main content

systemprompt_agent/services/shared/
error.rs

1//! Service-layer error type, distinct from the crate-public [`AgentError`]:
2//! it models failures internal to runtime services and converts into
3//! `AgentError` at the crate boundary.
4//!
5//! [`AgentError`]: crate::error::AgentError
6//!
7//! Copyright (c) systemprompt.io — Business Source License 1.1.
8//! See <https://systemprompt.io> for licensing details.
9
10use thiserror::Error;
11
12#[derive(Debug, Error)]
13pub enum AgentServiceError {
14    #[error("database operation failed: {0}")]
15    Database(String),
16
17    #[error("repository operation failed: {0}")]
18    Repository(String),
19
20    #[error("network request failed: {0}")]
21    Network(String),
22
23    #[error("authentication failed: {0}")]
24    Authentication(String),
25
26    #[error("authorization failed for resource: {0}")]
27    Authorization(String),
28
29    #[error("validation failed: {0}: {1}")]
30    Validation(String, String),
31
32    #[error("resource not found: {0}")]
33    NotFound(String),
34
35    #[error("service unavailable: {0}")]
36    ServiceUnavailable(String),
37
38    #[error("operation timed out after {0}ms")]
39    Timeout(u64),
40
41    #[error("configuration error: {0}: {1}")]
42    Configuration(String, String),
43
44    #[error("conflict: {0}")]
45    Conflict(String),
46
47    #[error("internal error: {0}")]
48    Internal(String),
49
50    #[error("logging error: {0}")]
51    Logging(String),
52
53    #[error("capacity exceeded: {0}")]
54    Capacity(String),
55
56    #[error("stream consumer closed before the task finished")]
57    StreamClosed,
58
59    #[error("task was cancelled before it finished")]
60    TaskCancelled,
61
62    #[error("skill {skill_id} is managed but withheld ({reason})")]
63    SkillWithheld {
64        skill_id: systemprompt_identifiers::SkillId,
65        reason: &'static str,
66    },
67
68    #[error("skill {skill_id} could not be resolved: {source}")]
69    SkillSource {
70        skill_id: systemprompt_identifiers::SkillId,
71        #[source]
72        source: systemprompt_traits::ManagedSkillResolverError,
73    },
74}
75
76impl From<std::io::Error> for AgentServiceError {
77    fn from(err: std::io::Error) -> Self {
78        Self::Internal(format!("io: {err}"))
79    }
80}
81
82impl From<sqlx::Error> for AgentServiceError {
83    fn from(err: sqlx::Error) -> Self {
84        Self::Database(err.to_string())
85    }
86}
87
88impl From<crate::repository::RepositoryError> for AgentServiceError {
89    fn from(err: crate::repository::RepositoryError) -> Self {
90        Self::Repository(err.to_string())
91    }
92}
93
94impl From<systemprompt_database::RepositoryError> for AgentServiceError {
95    fn from(err: systemprompt_database::RepositoryError) -> Self {
96        Self::Repository(err.to_string())
97    }
98}
99
100impl From<crate::error::AgentError> for AgentServiceError {
101    fn from(err: crate::error::AgentError) -> Self {
102        Self::Internal(err.to_string())
103    }
104}
105
106impl From<systemprompt_models::errors::AiInferenceError> for AgentServiceError {
107    fn from(err: systemprompt_models::errors::AiInferenceError) -> Self {
108        Self::Internal(err.to_string())
109    }
110}
111
112impl From<systemprompt_models::errors::McpRegistryError> for AgentServiceError {
113    fn from(err: systemprompt_models::errors::McpRegistryError) -> Self {
114        Self::Internal(err.to_string())
115    }
116}
117
118impl From<reqwest::Error> for AgentServiceError {
119    fn from(err: reqwest::Error) -> Self {
120        Self::Network(
121            err.url()
122                .map_or_else(|| "unknown".to_owned(), ToString::to_string),
123        )
124    }
125}
126
127pub type Result<T> = std::result::Result<T, AgentServiceError>;