1use thiserror::Error;
2
3#[derive(Error)]
4pub enum Error<T: pijul_core::GraphTxnT + pijul_core::TreeTxnT> {
5 #[error(transparent)]
6 Remote(#[from] RemoteError),
7 #[error(transparent)]
8 Interaction(#[from] pijul_interaction::InteractionError),
9 #[error("{0}")]
10 Graph(<T as pijul_core::GraphTxnT>::GraphError),
11 #[error(transparent)]
12 TxnErrGraph(pijul_core::pristine::TxnErr<<T as pijul_core::GraphTxnT>::GraphError>),
13 #[error(transparent)]
14 SmallString(#[from] pijul_core::small_string::Error),
15 #[error(transparent)]
16 Sanakirja(#[from] pijul_core::pristine::sanakirja::SanakirjaError),
17 #[error(transparent)]
18 TxnErrSanakirja(
19 #[from] pijul_core::pristine::TxnErr<pijul_core::pristine::sanakirja::SanakirjaError>,
20 ),
21 #[error(transparent)]
22 Archive(
23 #[from]
24 pijul_core::output::ArchiveError<
25 pijul_core::changestore::filesystem::Error,
26 T,
27 std::io::Error,
28 >,
29 ),
30 #[error("Concurrency")]
31 Concurrency,
32 #[error(transparent)]
33 Apply(#[from] pijul_core::ApplyError<pijul_core::changestore::filesystem::Error, T>),
34 #[error(transparent)]
35 FsError(#[from] pijul_core::fs::FsErrorC<pijul_core::changestore::filesystem::Error, T>),
36}
37
38impl<T: pijul_core::GraphTxnT + pijul_core::TreeTxnT> std::fmt::Debug for Error<T> {
39 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
40 match self {
41 Error::Remote(e) => std::fmt::Debug::fmt(e, f),
42 Error::Interaction(e) => std::fmt::Debug::fmt(e, f),
43 Error::Graph(e) => std::fmt::Debug::fmt(e, f),
44 Error::TxnErrGraph(e) => std::fmt::Debug::fmt(e, f),
45 Error::SmallString(e) => std::fmt::Debug::fmt(e, f),
46 Error::Sanakirja(e) => std::fmt::Debug::fmt(e, f),
47 Error::TxnErrSanakirja(e) => std::fmt::Debug::fmt(e, f),
48 Error::Archive(e) => std::fmt::Debug::fmt(e, f),
49 Error::Concurrency => write!(f, "Concurrency"),
50 Error::Apply(e) => std::fmt::Debug::fmt(e, f),
51 Error::FsError(e) => std::fmt::Debug::fmt(e, f),
52 }
53 }
54}
55
56#[derive(Debug, Error)]
57pub enum RemoteError {
58 #[error(transparent)]
60 Io(#[from] std::io::Error),
61 #[error(transparent)]
62 Reqwest(#[from] reqwest::Error),
63 #[error(transparent)]
64 Thrussh(#[from] thrussh::Error),
65 #[error(transparent)]
66 ThrusshKeys(#[from] thrussh_keys::Error),
67 #[error(transparent)]
68 SerdeJson(#[from] serde_json::Error),
69 #[error(transparent)]
70 FromUtf8(#[from] std::string::FromUtf8Error),
71 #[error(transparent)]
72 Utf8(#[from] std::str::Utf8Error),
73 #[error(transparent)]
74 Sanakirja(#[from] pijul_core::pristine::sanakirja::SanakirjaError),
75 #[error(transparent)]
76 SmallString(#[from] pijul_core::small_string::Error),
77 #[error(transparent)]
78 HashPrefix(
79 #[from]
80 pijul_core::pristine::HashPrefixError<pijul_core::pristine::sanakirja::SanakirjaError>,
81 ),
82 #[error(transparent)]
83 TxnSanakirja(
84 #[from] pijul_core::pristine::TxnErr<pijul_core::pristine::sanakirja::SanakirjaError>,
85 ),
86 #[error(transparent)]
87 TreeSanakirja(
88 #[from] pijul_core::pristine::TreeErr<pijul_core::pristine::sanakirja::SanakirjaError>,
89 ),
90 #[error(transparent)]
91 Config(#[from] pijul_config::ConfigError),
92 #[error(transparent)]
93 Identity(#[from] pijul_identity::IdentityError),
94 #[error(transparent)]
95 Repository(#[from] pijul_repository::RepositoryError),
96 #[error(transparent)]
97 CoreRemote(#[from] pijul_core::RemoteError),
98 #[error(transparent)]
99 Url(#[from] url::ParseError),
100 #[error(transparent)]
101 JoinError(#[from] tokio::task::JoinError),
102 #[error(transparent)]
103 Interaction(#[from] pijul_interaction::InteractionError),
104 #[error(transparent)]
105 ChangeFile(#[from] pijul_core::change::ChangeError),
106 #[error(transparent)]
107 Filesystem(#[from] pijul_core::changestore::filesystem::Error),
108 #[error("Concurrency")]
109 Concurrency,
110
111 #[error("Dependency missing: {hash:?}")]
113 DependencyMissing { hash: pijul_core::pristine::Hash },
114 #[error("Change already on channel: {hash:?}")]
115 ChangeAlreadyOnChannel { hash: pijul_core::pristine::Hash },
116 #[error("Invalid change")]
117 InvalidChange,
118 #[error("Corruption detected")]
119 Corruption,
120
121 #[error("{0}")]
123 Local(<crate::local::LocalTxn as pijul_core::GraphTxnT>::GraphError),
124 #[error("{0}")]
125 LocalTxn(
126 pijul_core::pristine::TxnErr<<crate::local::LocalTxn as pijul_core::GraphTxnT>::GraphError>,
127 ),
128 #[error(transparent)]
129 Apply(
130 #[from]
131 pijul_core::ApplyError<pijul_core::changestore::filesystem::Error, crate::local::LocalTxn>,
132 ),
133 #[error("Remote not found: {0:?}")]
134 RemoteNotFound(String),
135 #[error("Ambiguous path: {0:?}")]
136 AmbiguousPath(String),
137 #[error("Remote scheme not supported: {0:?}")]
138 UnsupportedScheme(String),
139 #[error("Channel not found")]
140 ChannelNotFound,
141 #[error("Channel {0} does not exist in repository {1}")]
142 LocalChannelNotFound(String, String),
143 #[error("State not found: {0:?}")]
144 StateNotFound(pijul_core::pristine::Merkle),
145 #[error("Cannot apply tag {tag:?}: channel does not have that state")]
146 TagNotInChannel { tag: pijul_core::pristine::Merkle },
147 #[error("Not authenticated. Please check your credentials and try again.")]
148 SshAuthFailed,
149 #[error("Remote exited with status {0:?}")]
150 RemoteExited(u32),
151 #[error("HTTP error: {0}")]
152 HttpError(reqwest::StatusCode),
153 #[error("HTTP server returned an error: {0}")]
154 HttpServerError(String),
155 #[error("Repository `{0}` not found (404)")]
156 HttpNotFound(String),
157 #[error("Tag already downloaded: {0:?}")]
158 TagAlreadyDownloaded(pijul_core::pristine::Merkle),
159 #[error("Protocol error")]
160 ProtocolError,
161 #[error("{0}")]
162 SshRemoteError(String),
163 #[error("Failed to decode local repository name")]
164 InvalidRepositoryName,
165 #[error("No parent path")]
166 NoPathParent,
167 #[error("Internal channel closed")]
168 ChannelClosed,
169 #[error("Unsupported operation: {0}")]
170 UnsupportedOperation(&'static str),
171 #[error("Remote sent an error")]
172 RemoteSentAnError,
173 #[error("{0}")]
174 RemoteError(String),
175}