systemprompt_sync/
error.rs1use systemprompt_models::domain_error;
4
5domain_error! {
6 pub enum SyncError {
7 common: [io, http, json, yaml],
8
9 #[error("API error {status}: {message}")]
10 ApiError { status: u16, message: String },
11
12 #[error("Unauthorized - run 'systemprompt cloud login'")]
13 Unauthorized,
14
15 #[error("Tenant has no associated app")]
16 TenantNoApp,
17
18 #[error("Must run from project root (with infrastructure/ directory)")]
19 NotProjectRoot,
20
21 #[error("Command failed: {command}")]
22 CommandFailed { command: String },
23
24 #[error("Failed to spawn `{command}`: {source}")]
25 CommandSpawnFailed {
26 command: String,
27 #[source]
28 source: std::io::Error,
29 },
30
31 #[error("Failed to open file {path}: {source}")]
32 FileOpenFailed {
33 path: String,
34 #[source]
35 source: std::io::Error,
36 },
37
38 #[error("Docker login failed")]
39 DockerLoginFailed,
40
41 #[error("Git SHA unavailable")]
42 GitShaUnavailable,
43
44 #[error("Missing configuration: {0}")]
45 MissingConfig(String),
46
47 #[error("Partial import failure after {completed}/{total} items: {message}")]
48 PartialImport {
49 completed: usize,
50 total: usize,
51 message: String,
52 },
53
54 #[error("Unsafe tarball entry rejected: {0}")]
55 TarballUnsafe(String),
56
57 #[error("Database error: {0}")]
58 Database(#[from] sqlx::Error),
59
60 #[error("Path error: {0}")]
61 StripPrefix(#[from] std::path::StripPrefixError),
62
63 #[error("Zip error: {0}")]
64 Zip(#[from] zip::result::ZipError),
65
66 #[error("Invalid input: {0}")]
67 InvalidInput(String),
68
69 #[error("internal: {0}")]
70 Internal(String),
71 }
72}
73
74impl SyncError {
75 pub fn internal(cause: impl std::fmt::Display) -> Self {
76 Self::Internal(cause.to_string())
77 }
78
79 pub fn invalid_input(cause: impl std::fmt::Display) -> Self {
80 Self::InvalidInput(cause.to_string())
81 }
82
83 pub const fn is_retryable(&self) -> bool {
84 matches!(self, Self::Http(_))
85 || matches!(
86 self,
87 Self::ApiError { status, .. }
88 if *status == 502 || *status == 503 || *status == 504 || *status == 429
89 )
90 }
91}
92
93pub type SyncResult<T> = Result<T, SyncError>;