Skip to main content

anytype_rpc/
error.rs

1//! Errors returned by anytype-rpc gRPC operations.
2
3use snafu::prelude::*;
4
5/// Unified error type for anytype-rpc gRPC operations.
6#[derive(Debug, Snafu)]
7#[snafu(visibility(pub))]
8pub enum AnytypeGrpcError {
9    /// Authentication error.
10    #[snafu(display("Auth error: {source}"))]
11    Auth { source: AuthError },
12
13    /// Configuration error.
14    #[snafu(display("Config error: {source}"))]
15    Config { source: ConfigError },
16
17    /// View operation error.
18    #[snafu(display("View error: {source}"))]
19    View { source: ViewError },
20
21    /// Space backup operation error.
22    #[snafu(display("Backup error: {source}"))]
23    Backup { source: BackupError },
24
25    /// gRPC transport connection error.
26    #[snafu(display("Transport error: {source}"))]
27    Transport { source: tonic::transport::Error },
28}
29
30/// Errors from authentication operations.
31#[derive(Debug, Snafu)]
32#[snafu(visibility(pub))]
33pub enum AuthError {
34    /// gRPC status error from a request.
35    #[snafu(display("Transport error: {source}"))]
36    Status { source: tonic::Status },
37
38    /// Anytype API returned an error response.
39    #[snafu(display("API error ({code}): {description}"))]
40    Api { code: i32, description: String },
41
42    /// Create session returned an empty token.
43    #[snafu(display("Create session returned empty token"))]
44    EmptyToken,
45
46    /// Invalid metadata value for auth token.
47    #[snafu(display("Invalid metadata value: {source}"))]
48    InvalidMetadata {
49        source: tonic::metadata::errors::InvalidMetadataValue,
50    },
51}
52
53/// Errors from configuration operations.
54#[derive(Debug, Snafu)]
55#[snafu(visibility(pub))]
56pub enum ConfigError {
57    /// Config file I/O error.
58    #[snafu(display("I/O error: {source}"))]
59    Io { source: std::io::Error },
60
61    /// Config file parse error.
62    #[snafu(display("Parse error: {source}"))]
63    Parse { source: serde_json::Error },
64
65    /// HOME environment variable not set.
66    #[snafu(display("HOME environment variable not set"))]
67    MissingHome,
68}
69
70/// Errors from view operations.
71#[derive(Debug, Snafu)]
72#[snafu(visibility(pub))]
73pub enum ViewError {
74    /// gRPC status error from a request.
75    #[snafu(display("Transport error: {source}"))]
76    Rpc { source: tonic::Status },
77
78    /// Anytype API returned an error response.
79    #[snafu(display("API error ({code}): {description}"))]
80    ApiResponse { code: i32, description: String },
81
82    /// Object view missing in response.
83    #[snafu(display("Object view missing in response"))]
84    MissingObjectView,
85
86    /// Dataview block not found for view id.
87    #[snafu(display("Dataview block not found for view id {view_id}"))]
88    MissingDataviewBlock { view_id: String },
89
90    /// View id not found.
91    #[snafu(display("View id {view_id} not found"))]
92    MissingView { view_id: String },
93
94    /// View type not supported.
95    #[snafu(display("View id {view_id} is not a supported view (type {actual})"))]
96    NotSupportedView { view_id: String, actual: i32 },
97}
98
99/// Errors from space backup operations.
100#[derive(Debug, Snafu)]
101#[snafu(visibility(pub))]
102pub enum BackupError {
103    /// gRPC status error from a request.
104    #[snafu(display("Transport error: {source}"))]
105    BackupRpc { source: tonic::Status },
106
107    /// Anytype API returned an error response.
108    #[snafu(display("API error ({code}): {description}"))]
109    BackupApiResponse { code: i32, description: String },
110
111    /// Authentication token metadata was invalid.
112    #[snafu(display("Auth error: {source}"))]
113    BackupAuth { source: AuthError },
114
115    /// Backup options were invalid.
116    #[snafu(display("Invalid backup options: {message}"))]
117    InvalidOptions { message: String },
118
119    /// Failed to resolve the friendly name for a space.
120    #[snafu(display("Failed to resolve space name for {space_id}: {message}"))]
121    SpaceNameLookup { space_id: String, message: String },
122
123    /// Server response did not include an export path.
124    #[snafu(display("Backup response missing export path"))]
125    MissingExportPath,
126
127    /// Failed to create or access a local path.
128    #[snafu(display("I/O error for {path:?}: {source}"))]
129    BackupIo {
130        path: std::path::PathBuf,
131        source: std::io::Error,
132    },
133
134    /// Failed to move generated backup to its final target path.
135    #[snafu(display("Failed to move backup from {from:?} to {to:?}: {source}"))]
136    BackupMove {
137        from: std::path::PathBuf,
138        to: std::path::PathBuf,
139        source: std::io::Error,
140    },
141}
142
143// From impls for AuthError
144impl From<tonic::Status> for AuthError {
145    fn from(source: tonic::Status) -> Self {
146        AuthError::Status { source }
147    }
148}
149
150impl From<tonic::metadata::errors::InvalidMetadataValue> for AuthError {
151    fn from(source: tonic::metadata::errors::InvalidMetadataValue) -> Self {
152        AuthError::InvalidMetadata { source }
153    }
154}
155
156// From impls for ConfigError
157impl From<std::io::Error> for ConfigError {
158    fn from(source: std::io::Error) -> Self {
159        ConfigError::Io { source }
160    }
161}
162
163impl From<serde_json::Error> for ConfigError {
164    fn from(source: serde_json::Error) -> Self {
165        ConfigError::Parse { source }
166    }
167}
168
169// From impls for ViewError
170impl From<tonic::Status> for ViewError {
171    fn from(source: tonic::Status) -> Self {
172        ViewError::Rpc { source }
173    }
174}
175
176// From impls for BackupError
177impl From<tonic::Status> for BackupError {
178    fn from(source: tonic::Status) -> Self {
179        BackupError::BackupRpc { source }
180    }
181}
182
183impl From<AuthError> for BackupError {
184    fn from(source: AuthError) -> Self {
185        BackupError::BackupAuth { source }
186    }
187}
188
189// From impls for AnytypeGrpcError
190impl From<AuthError> for AnytypeGrpcError {
191    fn from(source: AuthError) -> Self {
192        AnytypeGrpcError::Auth { source }
193    }
194}
195
196impl From<ConfigError> for AnytypeGrpcError {
197    fn from(source: ConfigError) -> Self {
198        AnytypeGrpcError::Config { source }
199    }
200}
201
202impl From<ViewError> for AnytypeGrpcError {
203    fn from(source: ViewError) -> Self {
204        AnytypeGrpcError::View { source }
205    }
206}
207
208impl From<BackupError> for AnytypeGrpcError {
209    fn from(source: BackupError) -> Self {
210        AnytypeGrpcError::Backup { source }
211    }
212}
213
214impl From<tonic::transport::Error> for AnytypeGrpcError {
215    fn from(source: tonic::transport::Error) -> Self {
216        AnytypeGrpcError::Transport { source }
217    }
218}