systemprompt_cloud/error/
mod.rs1use thiserror::Error;
13
14mod messages;
15
16pub type CloudResult<T> = Result<T, CloudError>;
17
18#[derive(Debug, Error)]
19#[non_exhaustive]
20pub enum CloudError {
21 #[error("Authentication required.\n\nRun: systemprompt cloud login")]
22 NotAuthenticated,
23
24 #[error("Token expired.\n\nRun: systemprompt cloud login")]
25 TokenExpired,
26
27 #[error("JWT decode error")]
28 JwtDecode,
29
30 #[error("Credentials file corrupted.\n\nRun: systemprompt cloud login")]
31 CredentialsCorrupted {
32 #[source]
33 source: serde_json::Error,
34 },
35
36 #[error("Tenants not synced.\n\nRun: systemprompt cloud login")]
37 TenantsNotSynced,
38
39 #[error("Tenants store corrupted.\n\nRun: systemprompt cloud login")]
40 TenantsStoreCorrupted {
41 #[source]
42 source: serde_json::Error,
43 },
44
45 #[error("Tenants store invalid: {message}")]
46 TenantsStoreInvalid { message: String },
47
48 #[error("API error: {message}")]
49 ApiError { message: String },
50
51 #[error(transparent)]
52 Network(#[from] reqwest::Error),
53
54 #[error(transparent)]
55 Io(#[from] std::io::Error),
56
57 #[error(transparent)]
58 Json(#[from] serde_json::Error),
59
60 #[error("Cloud API validation failed: {message}")]
61 ApiValidationFailed { message: String },
62
63 #[error("Cloud credentials file invalid: {message}")]
64 InvalidCredentials { message: String },
65
66 #[error("Cloud credentials file not found: {path}")]
67 CredentialsFileNotFound { path: String },
68
69 #[error("Credentials not initialized")]
70 CredentialsNotInitialized,
71
72 #[error("Credentials already initialized")]
73 CredentialsAlreadyInitialized,
74
75 #[error(
76 "Session file version mismatch: expected {min}-{max}, got {actual}. Delete {path} and \
77 retry."
78 )]
79 SessionVersionMismatch {
80 min: u32,
81 max: u32,
82 actual: u32,
83 path: String,
84 },
85
86 #[error("OAuth flow failed: {message}")]
87 OAuthFlow { message: String },
88
89 #[error("Checkout flow failed: {message}")]
90 CheckoutFlow { message: String },
91
92 #[error("SSE stream error: {message}")]
93 SseStream { message: String },
94
95 #[error("Provisioning failed: {message}")]
96 ProvisioningFailed { message: String },
97
98 #[error("{message}")]
99 Deploy {
100 message: String,
101 #[source]
102 source: Option<Box<dyn std::error::Error + Send + Sync>>,
103 },
104
105 #[error("{message}")]
106 Dockerfile { message: String },
107
108 #[error("{message}")]
109 Docker {
110 message: String,
111 #[source]
112 source: Option<Box<dyn std::error::Error + Send + Sync>>,
113 },
114
115 #[error("Authentication failed. Please run 'systemprompt cloud login' again.")]
116 Unauthorized,
117
118 #[error("Request failed with status {status}: {body}")]
119 HttpStatus { status: u16, body: String },
120
121 #[error("{message}")]
122 Other { message: String },
123}
124
125impl CloudError {
126 pub fn other(message: impl Into<String>) -> Self {
127 Self::Other {
128 message: message.into(),
129 }
130 }
131
132 pub fn deploy(message: impl Into<String>) -> Self {
133 Self::Deploy {
134 message: message.into(),
135 source: None,
136 }
137 }
138
139 pub fn deploy_with(
140 message: impl Into<String>,
141 source: impl Into<Box<dyn std::error::Error + Send + Sync>>,
142 ) -> Self {
143 Self::Deploy {
144 message: message.into(),
145 source: Some(source.into()),
146 }
147 }
148
149 pub fn dockerfile(message: impl Into<String>) -> Self {
150 Self::Dockerfile {
151 message: message.into(),
152 }
153 }
154
155 pub fn docker(message: impl Into<String>) -> Self {
156 Self::Docker {
157 message: message.into(),
158 source: None,
159 }
160 }
161
162 pub fn docker_with(
163 message: impl Into<String>,
164 source: impl Into<Box<dyn std::error::Error + Send + Sync>>,
165 ) -> Self {
166 Self::Docker {
167 message: message.into(),
168 source: Some(source.into()),
169 }
170 }
171
172 pub const fn is_missing_credentials_file(&self) -> bool {
173 matches!(self, Self::CredentialsFileNotFound { .. })
174 }
175
176 pub const fn is_local_mode_recoverable(&self) -> bool {
177 matches!(
178 self,
179 Self::CredentialsFileNotFound { .. }
180 | Self::TokenExpired
181 | Self::ApiValidationFailed { .. }
182 )
183 }
184}