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