Skip to main content

syncweb_core/
error.rs

1use std::{error::Error as StdError, fmt::Display, path::PathBuf};
2
3use thiserror::Error;
4
5pub type Result<T> = std::result::Result<T, SyncwebError>;
6pub type BoxError = Box<dyn StdError + Send + Sync + 'static>;
7
8/// Top-level error type for syncweb-core library operations.
9#[derive(Debug, Error)]
10#[non_exhaustive]
11pub enum SyncwebError {
12    #[error("folder not found: {0}")]
13    FolderNotFound(String),
14
15    #[error("no synchronized folders are available")]
16    NoFolders,
17
18    #[error("folder selector {0:?} is not a namespace ID and more than one synchronized folder is available")]
19    AmbiguousFolderSelector(String),
20
21    #[error("folder already managed")]
22    FolderAlreadyManaged,
23
24    #[error("folder mode {mode} does not permit local writes")]
25    WriteDenied { mode: String },
26
27    #[error("invalid doc ticket: {0}")]
28    InvalidTicket(String),
29
30    #[error("invalid configuration: {0}")]
31    InvalidConfig(String),
32
33    #[error("invalid identity: {0}")]
34    InvalidIdentity(String),
35
36    #[error("invalid device ID: {0}")]
37    InvalidDeviceId(String),
38
39    #[error("invalid sync mode: {0}")]
40    InvalidSyncMode(String),
41
42    #[error("syncthing relay fallback is disabled")]
43    RelayDisabled,
44
45    #[error("no syncthing relay is reachable: {reasons}")]
46    RelayUnreachable { reasons: String },
47
48    #[error("relay frame exceeds {max} byte limit")]
49    RelayFrameTooLarge { max: usize },
50
51    #[error("relay message decode error: {0}")]
52    RelayDecode(String),
53
54    #[error("relay URL must use tcp:// scheme")]
55    RelayBadScheme,
56
57    #[error("relay URL must contain a host and port: {0}")]
58    RelayBadAddress(String),
59
60    #[error("HKDF key derivation failed: {0}")]
61    KeyDerivation(String),
62
63    #[error("identity file error at {path}: {source}")]
64    Identity {
65        path: PathBuf,
66        #[source]
67        source: BoxError,
68    },
69
70    #[error("{context}: {detail}")]
71    Operation { context: String, detail: String },
72
73    #[error("blob size exceeds u64::MAX")]
74    BlobTooLarge,
75
76    #[error("namespace could not be opened")]
77    NamespaceNotAvailable,
78
79    #[error("missing cryptographic signature: {0}")]
80    MissingSignature(String),
81
82    #[error("invalid cryptographic signature: {0}")]
83    InvalidSignature(String),
84
85    #[error("access denied: {0}")]
86    AccessDenied(String),
87
88    #[error(transparent)]
89    Io(#[from] std::io::Error),
90}
91
92impl SyncwebError {
93    pub fn identity(path: impl Into<PathBuf>, source: impl StdError + Send + Sync + 'static) -> Self {
94        Self::Identity {
95            path: path.into(),
96            source: Box::new(source),
97        }
98    }
99
100    pub fn operation(context: impl Into<String>, source: impl Display) -> Self {
101        Self::Operation {
102            context: context.into(),
103            detail: source.to_string(),
104        }
105    }
106
107    pub fn access_denied(reason: impl Into<String>) -> Self {
108        Self::AccessDenied(reason.into())
109    }
110}