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